@inquirer/select 2.4.6 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -118,6 +118,8 @@ Here's each property:
118
118
  - `short`: Once the prompt is done (press enter), we'll use `short` if defined to render next to the question. By default we'll use `name`.
119
119
  - `disabled`: Disallow the option from being selected. If `disabled` is a string, it'll be used as a help tip explaining why the choice isn't available.
120
120
 
121
+ `choices` can also be an array of string, in which case the string will be used both as the `value` and the `name`.
122
+
121
123
  ## Theming
122
124
 
123
125
  You can theme a prompt by passing a `theme` object option. The theme object only need to includes the keys you wish to modify, we'll fallback on the defaults for the rest.
package/dist/cjs/index.js CHANGED
@@ -19,14 +19,37 @@ const selectTheme = {
19
19
  function isSelectable(item) {
20
20
  return !core_1.Separator.isSeparator(item) && !item.disabled;
21
21
  }
22
+ function normalizeChoices(choices) {
23
+ return choices.map((choice) => {
24
+ var _a, _b, _c;
25
+ if (core_1.Separator.isSeparator(choice))
26
+ return choice;
27
+ if (typeof choice === 'string') {
28
+ return {
29
+ value: choice,
30
+ name: choice,
31
+ short: choice,
32
+ disabled: false,
33
+ };
34
+ }
35
+ const name = (_a = choice.name) !== null && _a !== void 0 ? _a : String(choice.value);
36
+ return {
37
+ value: choice.value,
38
+ name,
39
+ description: choice.description,
40
+ short: (_b = choice.short) !== null && _b !== void 0 ? _b : name,
41
+ disabled: (_c = choice.disabled) !== null && _c !== void 0 ? _c : false,
42
+ };
43
+ });
44
+ }
22
45
  exports.default = (0, core_1.createPrompt)((config, done) => {
23
- var _a, _b;
24
- const { choices: items, loop = true, pageSize = 7 } = config;
46
+ const { loop = true, pageSize = 7 } = config;
25
47
  const firstRender = (0, core_1.useRef)(true);
26
48
  const theme = (0, core_1.makeTheme)(selectTheme, config.theme);
27
49
  const prefix = (0, core_1.usePrefix)({ theme });
28
50
  const [status, setStatus] = (0, core_1.useState)('pending');
29
51
  const searchTimeoutRef = (0, core_1.useRef)();
52
+ const items = (0, core_1.useMemo)(() => normalizeChoices(config.choices), [config.choices]);
30
53
  const bounds = (0, core_1.useMemo)(() => {
31
54
  const first = items.findIndex(isSelectable);
32
55
  const last = items.findLastIndex(isSelectable);
@@ -79,9 +102,7 @@ exports.default = (0, core_1.createPrompt)((config, done) => {
79
102
  const matchIndex = items.findIndex((item) => {
80
103
  if (core_1.Separator.isSeparator(item) || !isSelectable(item))
81
104
  return false;
82
- return String(item.name || item.value)
83
- .toLowerCase()
84
- .startsWith(searchTerm);
105
+ return item.name.toLowerCase().startsWith(searchTerm);
85
106
  });
86
107
  if (matchIndex >= 0) {
87
108
  setActive(matchIndex);
@@ -114,23 +135,19 @@ exports.default = (0, core_1.createPrompt)((config, done) => {
114
135
  if (core_1.Separator.isSeparator(item)) {
115
136
  return ` ${item.separator}`;
116
137
  }
117
- const line = String(item.name || item.value);
118
138
  if (item.disabled) {
119
139
  const disabledLabel = typeof item.disabled === 'string' ? item.disabled : '(disabled)';
120
- return theme.style.disabled(`${line} ${disabledLabel}`);
140
+ return theme.style.disabled(`${item.name} ${disabledLabel}`);
121
141
  }
122
142
  const color = isActive ? theme.style.highlight : (x) => x;
123
143
  const cursor = isActive ? theme.icon.cursor : ` `;
124
- return color(`${cursor} ${line}`);
144
+ return color(`${cursor} ${item.name}`);
125
145
  },
126
146
  pageSize,
127
147
  loop,
128
148
  });
129
149
  if (status === 'done') {
130
- const answer = (_b = (_a = selectedChoice.short) !== null && _a !== void 0 ? _a : selectedChoice.name) !== null && _b !== void 0 ? _b :
131
- // TODO: Could we enforce that at the type level? Name should be defined for non-string values.
132
- String(selectedChoice.value);
133
- return `${prefix} ${message} ${theme.style.answer(answer)}`;
150
+ return `${prefix} ${message} ${theme.style.answer(selectedChoice.short)}`;
134
151
  }
135
152
  const choiceDescription = selectedChoice.description
136
153
  ? `\n${theme.style.description(selectedChoice.description)}`
@@ -20,7 +20,7 @@ type Choice<Value> = {
20
20
  };
21
21
  declare const _default: <Value>(config: {
22
22
  message: string;
23
- choices: readonly (Separator | Choice<Value>)[];
23
+ choices: readonly (string | Separator)[] | readonly (Separator | Choice<Value>)[];
24
24
  pageSize?: number | undefined;
25
25
  loop?: boolean | undefined;
26
26
  default?: unknown;
@@ -13,13 +13,36 @@ const selectTheme = {
13
13
  function isSelectable(item) {
14
14
  return !Separator.isSeparator(item) && !item.disabled;
15
15
  }
16
+ function normalizeChoices(choices) {
17
+ return choices.map((choice) => {
18
+ if (Separator.isSeparator(choice))
19
+ return choice;
20
+ if (typeof choice === 'string') {
21
+ return {
22
+ value: choice,
23
+ name: choice,
24
+ short: choice,
25
+ disabled: false,
26
+ };
27
+ }
28
+ const name = choice.name ?? String(choice.value);
29
+ return {
30
+ value: choice.value,
31
+ name,
32
+ description: choice.description,
33
+ short: choice.short ?? name,
34
+ disabled: choice.disabled ?? false,
35
+ };
36
+ });
37
+ }
16
38
  export default createPrompt((config, done) => {
17
- const { choices: items, loop = true, pageSize = 7 } = config;
39
+ const { loop = true, pageSize = 7 } = config;
18
40
  const firstRender = useRef(true);
19
41
  const theme = makeTheme(selectTheme, config.theme);
20
42
  const prefix = usePrefix({ theme });
21
43
  const [status, setStatus] = useState('pending');
22
44
  const searchTimeoutRef = useRef();
45
+ const items = useMemo(() => normalizeChoices(config.choices), [config.choices]);
23
46
  const bounds = useMemo(() => {
24
47
  const first = items.findIndex(isSelectable);
25
48
  const last = items.findLastIndex(isSelectable);
@@ -72,9 +95,7 @@ export default createPrompt((config, done) => {
72
95
  const matchIndex = items.findIndex((item) => {
73
96
  if (Separator.isSeparator(item) || !isSelectable(item))
74
97
  return false;
75
- return String(item.name || item.value)
76
- .toLowerCase()
77
- .startsWith(searchTerm);
98
+ return item.name.toLowerCase().startsWith(searchTerm);
78
99
  });
79
100
  if (matchIndex >= 0) {
80
101
  setActive(matchIndex);
@@ -107,24 +128,19 @@ export default createPrompt((config, done) => {
107
128
  if (Separator.isSeparator(item)) {
108
129
  return ` ${item.separator}`;
109
130
  }
110
- const line = String(item.name || item.value);
111
131
  if (item.disabled) {
112
132
  const disabledLabel = typeof item.disabled === 'string' ? item.disabled : '(disabled)';
113
- return theme.style.disabled(`${line} ${disabledLabel}`);
133
+ return theme.style.disabled(`${item.name} ${disabledLabel}`);
114
134
  }
115
135
  const color = isActive ? theme.style.highlight : (x) => x;
116
136
  const cursor = isActive ? theme.icon.cursor : ` `;
117
- return color(`${cursor} ${line}`);
137
+ return color(`${cursor} ${item.name}`);
118
138
  },
119
139
  pageSize,
120
140
  loop,
121
141
  });
122
142
  if (status === 'done') {
123
- const answer = selectedChoice.short ??
124
- selectedChoice.name ??
125
- // TODO: Could we enforce that at the type level? Name should be defined for non-string values.
126
- String(selectedChoice.value);
127
- return `${prefix} ${message} ${theme.style.answer(answer)}`;
143
+ return `${prefix} ${message} ${theme.style.answer(selectedChoice.short)}`;
128
144
  }
129
145
  const choiceDescription = selectedChoice.description
130
146
  ? `\n${theme.style.description(selectedChoice.description)}`
@@ -20,7 +20,7 @@ type Choice<Value> = {
20
20
  };
21
21
  declare const _default: <Value>(config: {
22
22
  message: string;
23
- choices: readonly (Separator | Choice<Value>)[];
23
+ choices: readonly (string | Separator)[] | readonly (Separator | Choice<Value>)[];
24
24
  pageSize?: number | undefined;
25
25
  loop?: boolean | undefined;
26
26
  default?: unknown;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inquirer/select",
3
- "version": "2.4.6",
3
+ "version": "2.5.0",
4
4
  "description": "Inquirer select/list prompt",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "typings": "./dist/cjs/types/index.d.ts",
@@ -54,14 +54,14 @@
54
54
  "license": "MIT",
55
55
  "homepage": "https://github.com/SBoudrias/Inquirer.js/blob/main/packages/select/README.md",
56
56
  "dependencies": {
57
- "@inquirer/core": "^9.0.9",
57
+ "@inquirer/core": "^9.1.0",
58
58
  "@inquirer/figures": "^1.0.5",
59
- "@inquirer/type": "^1.5.2",
59
+ "@inquirer/type": "^1.5.3",
60
60
  "ansi-escapes": "^4.3.2",
61
61
  "yoctocolors-cjs": "^2.1.2"
62
62
  },
63
63
  "devDependencies": {
64
- "@inquirer/testing": "^2.1.31"
64
+ "@inquirer/testing": "^2.1.32"
65
65
  },
66
66
  "scripts": {
67
67
  "tsc": "yarn run tsc:esm && yarn run tsc:cjs",
@@ -88,5 +88,5 @@
88
88
  }
89
89
  },
90
90
  "sideEffects": false,
91
- "gitHead": "056e26aa6497e0036864d032f9eb8d821de821e7"
91
+ "gitHead": "0c039599ef88fe9eb804fe083ee386ec906a856f"
92
92
  }