@inquirer/select 1.2.12 → 1.3.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/dist/cjs/index.js CHANGED
@@ -26,16 +26,19 @@ function renderItem({ item, isActive }) {
26
26
  return color(`${prefix} ${line}`);
27
27
  }
28
28
  exports.default = (0, core_1.createPrompt)((config, done) => {
29
- const { choices: items, pageSize } = config;
29
+ const { choices: items, loop = true, pageSize } = config;
30
30
  const firstRender = (0, core_1.useRef)(true);
31
31
  const prefix = (0, core_1.usePrefix)();
32
32
  const [status, setStatus] = (0, core_1.useState)('pending');
33
- const [active, setActive] = (0, core_1.useState)(() => {
34
- const selected = items.findIndex(isSelectable);
35
- if (selected < 0)
33
+ const bounds = (0, core_1.useMemo)(() => {
34
+ const first = items.findIndex(isSelectable);
35
+ // TODO: Replace with `findLastIndex` when it's available.
36
+ const last = items.length - 1 - [...items].reverse().findIndex(isSelectable);
37
+ if (first < 0)
36
38
  throw new Error('[select prompt] No selectable choices. All choices are disabled.');
37
- return selected;
38
- });
39
+ return { first, last };
40
+ }, [items]);
41
+ const [active, setActive] = (0, core_1.useState)(bounds.first);
39
42
  // Safe to assume the cursor position always point to a Choice.
40
43
  const selectedChoice = items[active];
41
44
  (0, core_1.useKeypress)((key) => {
@@ -44,6 +47,10 @@ exports.default = (0, core_1.createPrompt)((config, done) => {
44
47
  done(selectedChoice.value);
45
48
  }
46
49
  else if ((0, core_1.isUpKey)(key) || (0, core_1.isDownKey)(key)) {
50
+ if (!loop && active === bounds.first && (0, core_1.isUpKey)(key))
51
+ return;
52
+ if (!loop && active === bounds.last && (0, core_1.isDownKey)(key))
53
+ return;
47
54
  const offset = (0, core_1.isUpKey)(key) ? -1 : 1;
48
55
  let next = active;
49
56
  do {
@@ -64,12 +71,12 @@ exports.default = (0, core_1.createPrompt)((config, done) => {
64
71
  firstRender.current = false;
65
72
  message += chalk_1.default.dim(' (Use arrow keys)');
66
73
  }
67
- const lines = items
68
- .map((item, index) => renderItem({ item, isActive: index === active }))
69
- .join('\n');
70
- const page = (0, core_1.usePagination)(lines, {
74
+ const page = (0, core_1.usePagination)({
75
+ items,
71
76
  active,
77
+ renderItem,
72
78
  pageSize,
79
+ loop,
73
80
  });
74
81
  if (status === 'done') {
75
82
  return `${prefix} ${message} ${chalk_1.default.cyan(selectedChoice.name || selectedChoice.value)}`;
@@ -10,6 +10,7 @@ declare const _default: <Value extends unknown>(config: {
10
10
  message: string | Promise<string> | (() => Promise<string>);
11
11
  choices: readonly (Separator | Choice<Value>)[];
12
12
  pageSize?: number | undefined;
13
+ loop?: boolean | undefined;
13
14
  }, context?: import("@inquirer/type").Context | undefined) => import("@inquirer/type").CancelablePromise<Value>;
14
15
  export default _default;
15
16
  export { Separator };
@@ -1,4 +1,4 @@
1
- import { createPrompt, useState, useKeypress, usePrefix, usePagination, useRef, isEnterKey, isUpKey, isDownKey, isNumberKey, Separator, } from '@inquirer/core';
1
+ import { createPrompt, useState, useKeypress, usePrefix, usePagination, useRef, useMemo, isEnterKey, isUpKey, isDownKey, isNumberKey, Separator, } from '@inquirer/core';
2
2
  import chalk from 'chalk';
3
3
  import figures from 'figures';
4
4
  import ansiEscapes from 'ansi-escapes';
@@ -19,16 +19,19 @@ function renderItem({ item, isActive }) {
19
19
  return color(`${prefix} ${line}`);
20
20
  }
21
21
  export default createPrompt((config, done) => {
22
- const { choices: items, pageSize } = config;
22
+ const { choices: items, loop = true, pageSize } = config;
23
23
  const firstRender = useRef(true);
24
24
  const prefix = usePrefix();
25
25
  const [status, setStatus] = useState('pending');
26
- const [active, setActive] = useState(() => {
27
- const selected = items.findIndex(isSelectable);
28
- if (selected < 0)
26
+ const bounds = useMemo(() => {
27
+ const first = items.findIndex(isSelectable);
28
+ // TODO: Replace with `findLastIndex` when it's available.
29
+ const last = items.length - 1 - [...items].reverse().findIndex(isSelectable);
30
+ if (first < 0)
29
31
  throw new Error('[select prompt] No selectable choices. All choices are disabled.');
30
- return selected;
31
- });
32
+ return { first, last };
33
+ }, [items]);
34
+ const [active, setActive] = useState(bounds.first);
32
35
  // Safe to assume the cursor position always point to a Choice.
33
36
  const selectedChoice = items[active];
34
37
  useKeypress((key) => {
@@ -37,6 +40,10 @@ export default createPrompt((config, done) => {
37
40
  done(selectedChoice.value);
38
41
  }
39
42
  else if (isUpKey(key) || isDownKey(key)) {
43
+ if (!loop && active === bounds.first && isUpKey(key))
44
+ return;
45
+ if (!loop && active === bounds.last && isDownKey(key))
46
+ return;
40
47
  const offset = isUpKey(key) ? -1 : 1;
41
48
  let next = active;
42
49
  do {
@@ -57,12 +64,12 @@ export default createPrompt((config, done) => {
57
64
  firstRender.current = false;
58
65
  message += chalk.dim(' (Use arrow keys)');
59
66
  }
60
- const lines = items
61
- .map((item, index) => renderItem({ item, isActive: index === active }))
62
- .join('\n');
63
- const page = usePagination(lines, {
67
+ const page = usePagination({
68
+ items,
64
69
  active,
70
+ renderItem,
65
71
  pageSize,
72
+ loop,
66
73
  });
67
74
  if (status === 'done') {
68
75
  return `${prefix} ${message} ${chalk.cyan(selectedChoice.name || selectedChoice.value)}`;
@@ -10,6 +10,7 @@ declare const _default: <Value extends unknown>(config: {
10
10
  message: string | Promise<string> | (() => Promise<string>);
11
11
  choices: readonly (Separator | Choice<Value>)[];
12
12
  pageSize?: number | undefined;
13
+ loop?: boolean | undefined;
13
14
  }, context?: import("@inquirer/type").Context | undefined) => import("@inquirer/type").CancelablePromise<Value>;
14
15
  export default _default;
15
16
  export { Separator };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inquirer/select",
3
- "version": "1.2.12",
3
+ "version": "1.3.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/master/packages/select/README.md",
56
56
  "dependencies": {
57
- "@inquirer/core": "^5.0.1",
57
+ "@inquirer/core": "^5.1.0",
58
58
  "@inquirer/type": "^1.1.5",
59
59
  "ansi-escapes": "^4.3.2",
60
60
  "chalk": "^4.1.2",
61
61
  "figures": "^3.2.0"
62
62
  },
63
63
  "devDependencies": {
64
- "@inquirer/testing": "^2.1.7"
64
+ "@inquirer/testing": "^2.1.8"
65
65
  },
66
66
  "scripts": {
67
67
  "tsc": "yarn run tsc:esm && yarn run tsc:cjs",
@@ -86,5 +86,5 @@
86
86
  }
87
87
  }
88
88
  },
89
- "gitHead": "85784061d702778bc9dd48ca08f09ee9976b06ee"
89
+ "gitHead": "c88aaca660e58aa0fb079fe656c1004855e029da"
90
90
  }