@inquirer/checkbox
Advanced tools
@@ -1,2 +0,2 @@ | ||
| import { Separator, type Theme } from '@inquirer/core'; | ||
| import { Separator, type Theme, type Keybinding } from '@inquirer/core'; | ||
| import type { PartialDeep } from '@inquirer/type'; | ||
@@ -13,4 +13,7 @@ type CheckboxTheme = { | ||
| description: (text: string) => string; | ||
| keysHelpTip: (keys: [key: string, action: string][]) => string | undefined; | ||
| }; | ||
| /** @deprecated Use theme.style.keysHelpTip instead */ | ||
| helpMode: 'always' | 'never' | 'auto'; | ||
| keybindings: ReadonlyArray<Keybinding>; | ||
| }; | ||
@@ -24,2 +27,3 @@ type CheckboxShortcuts = { | ||
| name?: string; | ||
| checkedName?: string; | ||
| description?: string; | ||
@@ -34,2 +38,3 @@ short?: string; | ||
| name: string; | ||
| checkedName: string; | ||
| description?: string; | ||
@@ -36,0 +41,0 @@ short: string; |
+42
-40
@@ -21,4 +21,8 @@ "use strict"; | ||
| description: (text) => yoctocolors_cjs_1.default.cyan(text), | ||
| keysHelpTip: (keys) => keys | ||
| .map(([key, action]) => `${yoctocolors_cjs_1.default.bold(key)} ${yoctocolors_cjs_1.default.dim(action)}`) | ||
| .join(yoctocolors_cjs_1.default.dim(' • ')), | ||
| }, | ||
| helpMode: 'auto', | ||
| helpMode: 'always', | ||
| keybindings: [], | ||
| }; | ||
@@ -48,2 +52,3 @@ function isSelectable(item) { | ||
| short: choice, | ||
| checkedName: choice, | ||
| disabled: false, | ||
@@ -58,2 +63,3 @@ checked: false, | ||
| short: choice.short ?? name, | ||
| checkedName: choice.checkedName ?? name, | ||
| disabled: choice.disabled ?? false, | ||
@@ -69,6 +75,8 @@ checked: choice.checked ?? false, | ||
| exports.default = (0, core_1.createPrompt)((config, done) => { | ||
| const { instructions, pageSize = 7, loop = true, required, validate = () => true, } = config; | ||
| const { | ||
| // eslint-disable-next-line @typescript-eslint/no-deprecated | ||
| instructions, pageSize = 7, loop = true, required, validate = () => true, } = config; | ||
| const shortcuts = { all: 'a', invert: 'i', ...config.shortcuts }; | ||
| const theme = (0, core_1.makeTheme)(checkboxTheme, config.theme); | ||
| const firstRender = (0, core_1.useRef)(true); | ||
| const { keybindings } = theme; | ||
| const [status, setStatus] = (0, core_1.useState)('idle'); | ||
@@ -86,3 +94,2 @@ const prefix = (0, core_1.usePrefix)({ status, theme }); | ||
| const [active, setActive] = (0, core_1.useState)(bounds.first); | ||
| const [showHelpTip, setShowHelpTip] = (0, core_1.useState)(true); | ||
| const [errorMsg, setError] = (0, core_1.useState)(); | ||
@@ -104,7 +111,7 @@ (0, core_1.useKeypress)(async (key) => { | ||
| } | ||
| else if ((0, core_1.isUpKey)(key) || (0, core_1.isDownKey)(key)) { | ||
| else if ((0, core_1.isUpKey)(key, keybindings) || (0, core_1.isDownKey)(key, keybindings)) { | ||
| if (loop || | ||
| ((0, core_1.isUpKey)(key) && active !== bounds.first) || | ||
| ((0, core_1.isDownKey)(key) && active !== bounds.last)) { | ||
| const offset = (0, core_1.isUpKey)(key) ? -1 : 1; | ||
| ((0, core_1.isUpKey)(key, keybindings) && active !== bounds.first) || | ||
| ((0, core_1.isDownKey)(key, keybindings) && active !== bounds.last)) { | ||
| const offset = (0, core_1.isUpKey)(key, keybindings) ? -1 : 1; | ||
| let next = active; | ||
@@ -119,3 +126,2 @@ do { | ||
| setError(undefined); | ||
| setShowHelpTip(false); | ||
| setItems(items.map((choice, i) => (i === active ? toggle(choice) : choice))); | ||
@@ -164,5 +170,6 @@ } | ||
| const checkbox = item.checked ? theme.icon.checked : theme.icon.unchecked; | ||
| const name = item.checked ? item.checkedName : item.name; | ||
| const color = isActive ? theme.style.highlight : (x) => x; | ||
| const cursor = isActive ? theme.icon.cursor : ' '; | ||
| return color(`${cursor}${checkbox} ${item.name}`); | ||
| return color(`${cursor}${checkbox} ${name}`); | ||
| }, | ||
@@ -175,42 +182,37 @@ pageSize, | ||
| const answer = theme.style.answer(theme.style.renderSelectedChoices(selection, items)); | ||
| return `${prefix} ${message} ${answer}`; | ||
| return [prefix, message, answer].filter(Boolean).join(' '); | ||
| } | ||
| let helpTipTop = ''; | ||
| let helpTipBottom = ''; | ||
| if (theme.helpMode === 'always' || | ||
| (theme.helpMode === 'auto' && | ||
| showHelpTip && | ||
| (instructions === undefined || instructions))) { | ||
| let helpLine; | ||
| // eslint-disable-next-line @typescript-eslint/no-deprecated | ||
| if (theme.helpMode !== 'never' && instructions !== false) { | ||
| if (typeof instructions === 'string') { | ||
| helpTipTop = instructions; | ||
| helpLine = instructions; | ||
| } | ||
| else { | ||
| const keys = [ | ||
| `${theme.style.key('space')} to select`, | ||
| shortcuts.all ? `${theme.style.key(shortcuts.all)} to toggle all` : '', | ||
| shortcuts.invert | ||
| ? `${theme.style.key(shortcuts.invert)} to invert selection` | ||
| : '', | ||
| `and ${theme.style.key('enter')} to proceed`, | ||
| ['↑↓', 'navigate'], | ||
| ['space', 'select'], | ||
| ]; | ||
| helpTipTop = ` (Press ${keys.filter((key) => key !== '').join(', ')})`; | ||
| if (shortcuts.all) | ||
| keys.push([shortcuts.all, 'all']); | ||
| if (shortcuts.invert) | ||
| keys.push([shortcuts.invert, 'invert']); | ||
| keys.push(['⏎', 'submit']); | ||
| helpLine = theme.style.keysHelpTip(keys); | ||
| } | ||
| if (items.length > pageSize && | ||
| (theme.helpMode === 'always' || | ||
| // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
| (theme.helpMode === 'auto' && firstRender.current))) { | ||
| helpTipBottom = `\n${theme.style.help('(Use arrow keys to reveal more choices)')}`; | ||
| firstRender.current = false; | ||
| } | ||
| } | ||
| const choiceDescription = description | ||
| ? `\n${theme.style.description(description)}` | ||
| : ``; | ||
| let error = ''; | ||
| if (errorMsg) { | ||
| error = `\n${theme.style.error(errorMsg)}`; | ||
| } | ||
| return `${prefix} ${message}${helpTipTop}\n${page}${helpTipBottom}${choiceDescription}${error}${ansi_1.cursorHide}`; | ||
| const lines = [ | ||
| [prefix, message].filter(Boolean).join(' '), | ||
| page, | ||
| ' ', | ||
| description ? theme.style.description(description) : '', | ||
| errorMsg ? theme.style.error(errorMsg) : '', | ||
| helpLine, | ||
| ] | ||
| .filter(Boolean) | ||
| .join('\n') | ||
| .trimEnd(); | ||
| return `${lines}${ansi_1.cursorHide}`; | ||
| }); | ||
| var core_2 = require("@inquirer/core"); | ||
| Object.defineProperty(exports, "Separator", { enumerable: true, get: function () { return core_2.Separator; } }); |
@@ -1,2 +0,2 @@ | ||
| import { Separator, type Theme } from '@inquirer/core'; | ||
| import { Separator, type Theme, type Keybinding } from '@inquirer/core'; | ||
| import type { PartialDeep } from '@inquirer/type'; | ||
@@ -13,4 +13,7 @@ type CheckboxTheme = { | ||
| description: (text: string) => string; | ||
| keysHelpTip: (keys: [key: string, action: string][]) => string | undefined; | ||
| }; | ||
| /** @deprecated Use theme.style.keysHelpTip instead */ | ||
| helpMode: 'always' | 'never' | 'auto'; | ||
| keybindings: ReadonlyArray<Keybinding>; | ||
| }; | ||
@@ -24,2 +27,3 @@ type CheckboxShortcuts = { | ||
| name?: string; | ||
| checkedName?: string; | ||
| description?: string; | ||
@@ -34,2 +38,3 @@ short?: string; | ||
| name: string; | ||
| checkedName: string; | ||
| description?: string; | ||
@@ -36,0 +41,0 @@ short: string; |
+43
-41
@@ -1,2 +0,2 @@ | ||
| import { createPrompt, useState, useKeypress, usePrefix, usePagination, useRef, useMemo, makeTheme, isUpKey, isDownKey, isSpaceKey, isNumberKey, isEnterKey, ValidationError, Separator, } from '@inquirer/core'; | ||
| import { createPrompt, useState, useKeypress, usePrefix, usePagination, useMemo, makeTheme, isUpKey, isDownKey, isSpaceKey, isNumberKey, isEnterKey, ValidationError, Separator, } from '@inquirer/core'; | ||
| import { cursorHide } from '@inquirer/ansi'; | ||
@@ -15,4 +15,8 @@ import colors from 'yoctocolors-cjs'; | ||
| description: (text) => colors.cyan(text), | ||
| keysHelpTip: (keys) => keys | ||
| .map(([key, action]) => `${colors.bold(key)} ${colors.dim(action)}`) | ||
| .join(colors.dim(' • ')), | ||
| }, | ||
| helpMode: 'auto', | ||
| helpMode: 'always', | ||
| keybindings: [], | ||
| }; | ||
@@ -42,2 +46,3 @@ function isSelectable(item) { | ||
| short: choice, | ||
| checkedName: choice, | ||
| disabled: false, | ||
@@ -52,2 +57,3 @@ checked: false, | ||
| short: choice.short ?? name, | ||
| checkedName: choice.checkedName ?? name, | ||
| disabled: choice.disabled ?? false, | ||
@@ -63,6 +69,8 @@ checked: choice.checked ?? false, | ||
| export default createPrompt((config, done) => { | ||
| const { instructions, pageSize = 7, loop = true, required, validate = () => true, } = config; | ||
| const { | ||
| // eslint-disable-next-line @typescript-eslint/no-deprecated | ||
| instructions, pageSize = 7, loop = true, required, validate = () => true, } = config; | ||
| const shortcuts = { all: 'a', invert: 'i', ...config.shortcuts }; | ||
| const theme = makeTheme(checkboxTheme, config.theme); | ||
| const firstRender = useRef(true); | ||
| const { keybindings } = theme; | ||
| const [status, setStatus] = useState('idle'); | ||
@@ -80,3 +88,2 @@ const prefix = usePrefix({ status, theme }); | ||
| const [active, setActive] = useState(bounds.first); | ||
| const [showHelpTip, setShowHelpTip] = useState(true); | ||
| const [errorMsg, setError] = useState(); | ||
@@ -98,7 +105,7 @@ useKeypress(async (key) => { | ||
| } | ||
| else if (isUpKey(key) || isDownKey(key)) { | ||
| else if (isUpKey(key, keybindings) || isDownKey(key, keybindings)) { | ||
| if (loop || | ||
| (isUpKey(key) && active !== bounds.first) || | ||
| (isDownKey(key) && active !== bounds.last)) { | ||
| const offset = isUpKey(key) ? -1 : 1; | ||
| (isUpKey(key, keybindings) && active !== bounds.first) || | ||
| (isDownKey(key, keybindings) && active !== bounds.last)) { | ||
| const offset = isUpKey(key, keybindings) ? -1 : 1; | ||
| let next = active; | ||
@@ -113,3 +120,2 @@ do { | ||
| setError(undefined); | ||
| setShowHelpTip(false); | ||
| setItems(items.map((choice, i) => (i === active ? toggle(choice) : choice))); | ||
@@ -158,5 +164,6 @@ } | ||
| const checkbox = item.checked ? theme.icon.checked : theme.icon.unchecked; | ||
| const name = item.checked ? item.checkedName : item.name; | ||
| const color = isActive ? theme.style.highlight : (x) => x; | ||
| const cursor = isActive ? theme.icon.cursor : ' '; | ||
| return color(`${cursor}${checkbox} ${item.name}`); | ||
| return color(`${cursor}${checkbox} ${name}`); | ||
| }, | ||
@@ -169,41 +176,36 @@ pageSize, | ||
| const answer = theme.style.answer(theme.style.renderSelectedChoices(selection, items)); | ||
| return `${prefix} ${message} ${answer}`; | ||
| return [prefix, message, answer].filter(Boolean).join(' '); | ||
| } | ||
| let helpTipTop = ''; | ||
| let helpTipBottom = ''; | ||
| if (theme.helpMode === 'always' || | ||
| (theme.helpMode === 'auto' && | ||
| showHelpTip && | ||
| (instructions === undefined || instructions))) { | ||
| let helpLine; | ||
| // eslint-disable-next-line @typescript-eslint/no-deprecated | ||
| if (theme.helpMode !== 'never' && instructions !== false) { | ||
| if (typeof instructions === 'string') { | ||
| helpTipTop = instructions; | ||
| helpLine = instructions; | ||
| } | ||
| else { | ||
| const keys = [ | ||
| `${theme.style.key('space')} to select`, | ||
| shortcuts.all ? `${theme.style.key(shortcuts.all)} to toggle all` : '', | ||
| shortcuts.invert | ||
| ? `${theme.style.key(shortcuts.invert)} to invert selection` | ||
| : '', | ||
| `and ${theme.style.key('enter')} to proceed`, | ||
| ['↑↓', 'navigate'], | ||
| ['space', 'select'], | ||
| ]; | ||
| helpTipTop = ` (Press ${keys.filter((key) => key !== '').join(', ')})`; | ||
| if (shortcuts.all) | ||
| keys.push([shortcuts.all, 'all']); | ||
| if (shortcuts.invert) | ||
| keys.push([shortcuts.invert, 'invert']); | ||
| keys.push(['⏎', 'submit']); | ||
| helpLine = theme.style.keysHelpTip(keys); | ||
| } | ||
| if (items.length > pageSize && | ||
| (theme.helpMode === 'always' || | ||
| // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
| (theme.helpMode === 'auto' && firstRender.current))) { | ||
| helpTipBottom = `\n${theme.style.help('(Use arrow keys to reveal more choices)')}`; | ||
| firstRender.current = false; | ||
| } | ||
| } | ||
| const choiceDescription = description | ||
| ? `\n${theme.style.description(description)}` | ||
| : ``; | ||
| let error = ''; | ||
| if (errorMsg) { | ||
| error = `\n${theme.style.error(errorMsg)}`; | ||
| } | ||
| return `${prefix} ${message}${helpTipTop}\n${page}${helpTipBottom}${choiceDescription}${error}${cursorHide}`; | ||
| const lines = [ | ||
| [prefix, message].filter(Boolean).join(' '), | ||
| page, | ||
| ' ', | ||
| description ? theme.style.description(description) : '', | ||
| errorMsg ? theme.style.error(errorMsg) : '', | ||
| helpLine, | ||
| ] | ||
| .filter(Boolean) | ||
| .join('\n') | ||
| .trimEnd(); | ||
| return `${lines}${cursorHide}`; | ||
| }); | ||
| export { Separator } from '@inquirer/core'; |
+7
-7
| { | ||
| "name": "@inquirer/checkbox", | ||
| "version": "4.2.4", | ||
| "version": "4.3.0", | ||
| "description": "Inquirer checkbox prompt", | ||
@@ -77,6 +77,6 @@ "keywords": [ | ||
| "dependencies": { | ||
| "@inquirer/ansi": "^1.0.0", | ||
| "@inquirer/core": "^10.2.2", | ||
| "@inquirer/figures": "^1.0.13", | ||
| "@inquirer/type": "^3.0.8", | ||
| "@inquirer/ansi": "^1.0.1", | ||
| "@inquirer/core": "^10.3.0", | ||
| "@inquirer/figures": "^1.0.14", | ||
| "@inquirer/type": "^3.0.9", | ||
| "yoctocolors-cjs": "^2.1.2" | ||
@@ -86,3 +86,3 @@ }, | ||
| "@arethetypeswrong/cli": "^0.18.2", | ||
| "@inquirer/testing": "^2.1.50", | ||
| "@inquirer/testing": "^2.1.51", | ||
| "tshy": "^3.0.2" | ||
@@ -113,3 +113,3 @@ }, | ||
| }, | ||
| "gitHead": "3fdf43342deb468ee41d698e407d8800700e08dc" | ||
| "gitHead": "87cb01e67a25983bdaf0d74a7685915c0afb5f23" | ||
| } |
+21
-5
@@ -107,2 +107,3 @@ # `@inquirer/checkbox` | ||
| name?: string; | ||
| checkedName?: string; | ||
| description?: string; | ||
@@ -119,2 +120,3 @@ short?: string; | ||
| - `name`: This is the string displayed in the choice list. | ||
| - `checkedName`: Alternative `name` (or format) displayed when the choice is checked. | ||
| - `description`: Option for a longer description string that'll appear under the list when the cursor highlight a given choice. | ||
@@ -165,2 +167,3 @@ - `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`. | ||
| ) => string; | ||
| keysHelpTip: (keys: [key: string, action: string][]) => string | undefined; | ||
| }; | ||
@@ -172,12 +175,25 @@ icon: { | ||
| }; | ||
| helpMode: 'always' | 'never' | 'auto'; | ||
| }; | ||
| ``` | ||
| ### `theme.helpMode` | ||
| ### `theme.style.keysHelpTip` | ||
| - `auto` (default): Hide the help tips after an interaction occurs. The scroll tip will hide after any interactions, the selection tip will hide as soon as a first selection is done. | ||
| - `always`: The help tips will always show and never hide. | ||
| - `never`: The help tips will never show. | ||
| This function allows you to customize the keyboard shortcuts help tip displayed below the prompt. It receives an array of key-action pairs and should return a formatted string. You can also hook here to localize the labels to different languages. | ||
| It can also returns `undefined` to hide the help tip entirely. This is the replacement for the deprecated theme option `helpMode: 'never'`. | ||
| ```js | ||
| theme: { | ||
| style: { | ||
| keysHelpTip: (keys) => { | ||
| // Return undefined to hide the help tip completely | ||
| return undefined; | ||
| // Or customize the formatting. Or localize the labels. | ||
| return keys.map(([key, action]) => `${key}: ${action}`).join(' | '); | ||
| }; | ||
| } | ||
| } | ||
| ``` | ||
| # License | ||
@@ -184,0 +200,0 @@ |
31514
2.68%525
2.74%199
8.74%Updated
Updated
Updated
Updated