@inquirer/checkbox
Advanced tools
Comparing version 1.3.11 to 1.3.12
@@ -12,44 +12,64 @@ "use strict"; | ||
const ansi_escapes_1 = __importDefault(require("ansi-escapes")); | ||
function isSelectableChoice(choice) { | ||
return choice != null && !core_1.Separator.isSeparator(choice) && !choice.disabled; | ||
function isSelectable(item) { | ||
return !core_1.Separator.isSeparator(item) && !item.disabled; | ||
} | ||
function isChecked(item) { | ||
return isSelectable(item) && Boolean(item.checked); | ||
} | ||
function toggle(item) { | ||
return isSelectable(item) ? Object.assign(Object.assign({}, item), { checked: !item.checked }) : item; | ||
} | ||
function check(checked) { | ||
return function (item) { | ||
return isSelectable(item) ? Object.assign(Object.assign({}, item), { checked }) : item; | ||
}; | ||
} | ||
function renderItem({ item, isActive }) { | ||
if (core_1.Separator.isSeparator(item)) { | ||
return ` ${item.separator}`; | ||
} | ||
const line = item.name || item.value; | ||
if (item.disabled) { | ||
const disabledLabel = typeof item.disabled === 'string' ? item.disabled : '(disabled)'; | ||
return chalk_1.default.dim(`- ${line} ${disabledLabel}`); | ||
} | ||
const checkbox = item.checked ? chalk_1.default.green(figures_1.default.circleFilled) : figures_1.default.circle; | ||
const color = isActive ? chalk_1.default.cyan : (x) => x; | ||
const prefix = isActive ? figures_1.default.pointer : ' '; | ||
return color(`${prefix}${checkbox} ${line}`); | ||
} | ||
exports.default = (0, core_1.createPrompt)((config, done) => { | ||
const { prefix = (0, core_1.usePrefix)(), instructions } = config; | ||
const { prefix = (0, core_1.usePrefix)(), instructions, pageSize, choices } = config; | ||
const [status, setStatus] = (0, core_1.useState)('pending'); | ||
const [choices, setChoices] = (0, core_1.useState)(() => config.choices.map((choice) => (Object.assign({}, choice)))); | ||
const [cursorPosition, setCursorPosition] = (0, core_1.useState)(0); | ||
const [items, setItems] = (0, core_1.useState)(choices.map((choice) => (Object.assign({}, choice)))); | ||
const [active, setActive] = (0, core_1.useState)(() => { | ||
const selected = items.findIndex(isSelectable); | ||
if (selected < 0) | ||
throw new Error('[checkbox prompt] No selectable choices. All choices are disabled.'); | ||
return selected; | ||
}); | ||
const [showHelpTip, setShowHelpTip] = (0, core_1.useState)(true); | ||
(0, core_1.useKeypress)((key) => { | ||
let newCursorPosition = cursorPosition; | ||
if ((0, core_1.isEnterKey)(key)) { | ||
setStatus('done'); | ||
done(choices | ||
.filter((choice) => isSelectableChoice(choice) && choice.checked) | ||
.map((choice) => choice.value)); | ||
done(items.filter(isChecked).map((choice) => choice.value)); | ||
} | ||
else if ((0, core_1.isUpKey)(key) || (0, core_1.isDownKey)(key)) { | ||
const offset = (0, core_1.isUpKey)(key) ? -1 : 1; | ||
let selectedOption; | ||
while (!isSelectableChoice(selectedOption)) { | ||
newCursorPosition = | ||
(newCursorPosition + offset + choices.length) % choices.length; | ||
selectedOption = choices[newCursorPosition]; | ||
} | ||
setCursorPosition(newCursorPosition); | ||
let next = active; | ||
do { | ||
next = (next + offset + items.length) % items.length; | ||
} while (!isSelectable(items[next])); | ||
setActive(next); | ||
} | ||
else if ((0, core_1.isSpaceKey)(key)) { | ||
setShowHelpTip(false); | ||
setChoices(choices.map((choice, i) => { | ||
if (i === cursorPosition && isSelectableChoice(choice)) { | ||
return Object.assign(Object.assign({}, choice), { checked: !choice.checked }); | ||
} | ||
return choice; | ||
})); | ||
setItems(items.map((choice, i) => (i === active ? toggle(choice) : choice))); | ||
} | ||
else if (key.name === 'a') { | ||
const selectAll = Boolean(choices.find((choice) => isSelectableChoice(choice) && !choice.checked)); | ||
setChoices(choices.map((choice) => isSelectableChoice(choice) ? Object.assign(Object.assign({}, choice), { checked: selectAll }) : choice)); | ||
const selectAll = Boolean(items.find((choice) => isSelectable(choice) && !choice.checked)); | ||
setItems(items.map(check(selectAll))); | ||
} | ||
else if (key.name === 'i') { | ||
setChoices(choices.map((choice) => isSelectableChoice(choice) ? Object.assign(Object.assign({}, choice), { checked: !choice.checked }) : choice)); | ||
setItems(items.map(toggle)); | ||
} | ||
@@ -59,42 +79,20 @@ else if ((0, core_1.isNumberKey)(key)) { | ||
const position = Number(key.name) - 1; | ||
// Abort if the choice doesn't exists or if disabled | ||
if (!isSelectableChoice(choices[position])) { | ||
const item = items[position]; | ||
if (item == null || !isSelectable(item)) | ||
return; | ||
} | ||
setCursorPosition(position); | ||
setChoices(choices.map((choice, i) => { | ||
if (i === position && isSelectableChoice(choice)) { | ||
return Object.assign(Object.assign({}, choice), { checked: !choice.checked }); | ||
} | ||
return choice; | ||
})); | ||
setActive(position); | ||
setItems(items.map((choice, i) => (i === position ? toggle(choice) : choice))); | ||
} | ||
}); | ||
const message = chalk_1.default.bold(config.message); | ||
const allChoices = choices | ||
.map((choice, index) => { | ||
if (core_1.Separator.isSeparator(choice)) { | ||
return ` ${choice.separator}`; | ||
} | ||
const line = choice.name || choice.value; | ||
if (choice.disabled) { | ||
const disabledLabel = typeof choice.disabled === 'string' ? choice.disabled : '(disabled)'; | ||
return chalk_1.default.dim(`- ${line} ${disabledLabel}`); | ||
} | ||
const checkbox = choice.checked | ||
? chalk_1.default.green(figures_1.default.circleFilled) | ||
: figures_1.default.circle; | ||
if (index === cursorPosition) { | ||
return chalk_1.default.cyan(`${figures_1.default.pointer}${checkbox} ${line}`); | ||
} | ||
return ` ${checkbox} ${line}`; | ||
}) | ||
const lines = items | ||
.map((item, index) => renderItem({ item, isActive: index === active })) | ||
.join('\n'); | ||
const windowedChoices = (0, core_1.usePagination)(allChoices, { | ||
active: cursorPosition, | ||
pageSize: config.pageSize, | ||
const page = (0, core_1.usePagination)(lines, { | ||
active, | ||
pageSize, | ||
}); | ||
if (status === 'done') { | ||
const selection = choices | ||
.filter((choice) => isSelectableChoice(choice) && choice.checked) | ||
const selection = items | ||
.filter(isChecked) | ||
.map((choice) => choice.name || choice.value); | ||
@@ -118,3 +116,3 @@ return `${prefix} ${message} ${chalk_1.default.cyan(selection.join(', '))}`; | ||
} | ||
return `${prefix} ${message}${helpTip}\n${windowedChoices}${ansi_escapes_1.default.cursorHide}`; | ||
return `${prefix} ${message}${helpTip}\n${page}${ansi_escapes_1.default.cursorHide}`; | ||
}); |
@@ -12,44 +12,64 @@ "use strict"; | ||
const ansi_escapes_1 = __importDefault(require("ansi-escapes")); | ||
function isSelectableChoice(choice) { | ||
return choice != null && !core_1.Separator.isSeparator(choice) && !choice.disabled; | ||
function isSelectable(item) { | ||
return !core_1.Separator.isSeparator(item) && !item.disabled; | ||
} | ||
function isChecked(item) { | ||
return isSelectable(item) && Boolean(item.checked); | ||
} | ||
function toggle(item) { | ||
return isSelectable(item) ? Object.assign(Object.assign({}, item), { checked: !item.checked }) : item; | ||
} | ||
function check(checked) { | ||
return function (item) { | ||
return isSelectable(item) ? Object.assign(Object.assign({}, item), { checked }) : item; | ||
}; | ||
} | ||
function renderItem({ item, isActive }) { | ||
if (core_1.Separator.isSeparator(item)) { | ||
return ` ${item.separator}`; | ||
} | ||
const line = item.name || item.value; | ||
if (item.disabled) { | ||
const disabledLabel = typeof item.disabled === 'string' ? item.disabled : '(disabled)'; | ||
return chalk_1.default.dim(`- ${line} ${disabledLabel}`); | ||
} | ||
const checkbox = item.checked ? chalk_1.default.green(figures_1.default.circleFilled) : figures_1.default.circle; | ||
const color = isActive ? chalk_1.default.cyan : (x) => x; | ||
const prefix = isActive ? figures_1.default.pointer : ' '; | ||
return color(`${prefix}${checkbox} ${line}`); | ||
} | ||
exports.default = (0, core_1.createPrompt)((config, done) => { | ||
const { prefix = (0, core_1.usePrefix)(), instructions } = config; | ||
const { prefix = (0, core_1.usePrefix)(), instructions, pageSize, choices } = config; | ||
const [status, setStatus] = (0, core_1.useState)('pending'); | ||
const [choices, setChoices] = (0, core_1.useState)(() => config.choices.map((choice) => (Object.assign({}, choice)))); | ||
const [cursorPosition, setCursorPosition] = (0, core_1.useState)(0); | ||
const [items, setItems] = (0, core_1.useState)(choices.map((choice) => (Object.assign({}, choice)))); | ||
const [active, setActive] = (0, core_1.useState)(() => { | ||
const selected = items.findIndex(isSelectable); | ||
if (selected < 0) | ||
throw new Error('[checkbox prompt] No selectable choices. All choices are disabled.'); | ||
return selected; | ||
}); | ||
const [showHelpTip, setShowHelpTip] = (0, core_1.useState)(true); | ||
(0, core_1.useKeypress)((key) => { | ||
let newCursorPosition = cursorPosition; | ||
if ((0, core_1.isEnterKey)(key)) { | ||
setStatus('done'); | ||
done(choices | ||
.filter((choice) => isSelectableChoice(choice) && choice.checked) | ||
.map((choice) => choice.value)); | ||
done(items.filter(isChecked).map((choice) => choice.value)); | ||
} | ||
else if ((0, core_1.isUpKey)(key) || (0, core_1.isDownKey)(key)) { | ||
const offset = (0, core_1.isUpKey)(key) ? -1 : 1; | ||
let selectedOption; | ||
while (!isSelectableChoice(selectedOption)) { | ||
newCursorPosition = | ||
(newCursorPosition + offset + choices.length) % choices.length; | ||
selectedOption = choices[newCursorPosition]; | ||
} | ||
setCursorPosition(newCursorPosition); | ||
let next = active; | ||
do { | ||
next = (next + offset + items.length) % items.length; | ||
} while (!isSelectable(items[next])); | ||
setActive(next); | ||
} | ||
else if ((0, core_1.isSpaceKey)(key)) { | ||
setShowHelpTip(false); | ||
setChoices(choices.map((choice, i) => { | ||
if (i === cursorPosition && isSelectableChoice(choice)) { | ||
return Object.assign(Object.assign({}, choice), { checked: !choice.checked }); | ||
} | ||
return choice; | ||
})); | ||
setItems(items.map((choice, i) => (i === active ? toggle(choice) : choice))); | ||
} | ||
else if (key.name === 'a') { | ||
const selectAll = Boolean(choices.find((choice) => isSelectableChoice(choice) && !choice.checked)); | ||
setChoices(choices.map((choice) => isSelectableChoice(choice) ? Object.assign(Object.assign({}, choice), { checked: selectAll }) : choice)); | ||
const selectAll = Boolean(items.find((choice) => isSelectable(choice) && !choice.checked)); | ||
setItems(items.map(check(selectAll))); | ||
} | ||
else if (key.name === 'i') { | ||
setChoices(choices.map((choice) => isSelectableChoice(choice) ? Object.assign(Object.assign({}, choice), { checked: !choice.checked }) : choice)); | ||
setItems(items.map(toggle)); | ||
} | ||
@@ -59,42 +79,20 @@ else if ((0, core_1.isNumberKey)(key)) { | ||
const position = Number(key.name) - 1; | ||
// Abort if the choice doesn't exists or if disabled | ||
if (!isSelectableChoice(choices[position])) { | ||
const item = items[position]; | ||
if (item == null || !isSelectable(item)) | ||
return; | ||
} | ||
setCursorPosition(position); | ||
setChoices(choices.map((choice, i) => { | ||
if (i === position && isSelectableChoice(choice)) { | ||
return Object.assign(Object.assign({}, choice), { checked: !choice.checked }); | ||
} | ||
return choice; | ||
})); | ||
setActive(position); | ||
setItems(items.map((choice, i) => (i === position ? toggle(choice) : choice))); | ||
} | ||
}); | ||
const message = chalk_1.default.bold(config.message); | ||
const allChoices = choices | ||
.map((choice, index) => { | ||
if (core_1.Separator.isSeparator(choice)) { | ||
return ` ${choice.separator}`; | ||
} | ||
const line = choice.name || choice.value; | ||
if (choice.disabled) { | ||
const disabledLabel = typeof choice.disabled === 'string' ? choice.disabled : '(disabled)'; | ||
return chalk_1.default.dim(`- ${line} ${disabledLabel}`); | ||
} | ||
const checkbox = choice.checked | ||
? chalk_1.default.green(figures_1.default.circleFilled) | ||
: figures_1.default.circle; | ||
if (index === cursorPosition) { | ||
return chalk_1.default.cyan(`${figures_1.default.pointer}${checkbox} ${line}`); | ||
} | ||
return ` ${checkbox} ${line}`; | ||
}) | ||
const lines = items | ||
.map((item, index) => renderItem({ item, isActive: index === active })) | ||
.join('\n'); | ||
const windowedChoices = (0, core_1.usePagination)(allChoices, { | ||
active: cursorPosition, | ||
pageSize: config.pageSize, | ||
const page = (0, core_1.usePagination)(lines, { | ||
active, | ||
pageSize, | ||
}); | ||
if (status === 'done') { | ||
const selection = choices | ||
.filter((choice) => isSelectableChoice(choice) && choice.checked) | ||
const selection = items | ||
.filter(isChecked) | ||
.map((choice) => choice.name || choice.value); | ||
@@ -118,3 +116,3 @@ return `${prefix} ${message} ${chalk_1.default.cyan(selection.join(', '))}`; | ||
} | ||
return `${prefix} ${message}${helpTip}\n${windowedChoices}${ansi_escapes_1.default.cursorHide}`; | ||
return `${prefix} ${message}${helpTip}\n${page}${ansi_escapes_1.default.cursorHide}`; | ||
}); |
import { Separator } from '@inquirer/core'; | ||
export type Choice<Value> = { | ||
type Choice<Value> = { | ||
name?: string; | ||
@@ -4,0 +4,0 @@ value: Value; |
{ | ||
"name": "@inquirer/checkbox", | ||
"version": "1.3.11", | ||
"version": "1.3.12", | ||
"engines": { | ||
@@ -60,4 +60,4 @@ "node": ">=14.18.0" | ||
"dependencies": { | ||
"@inquirer/core": "^5.0.0", | ||
"@inquirer/type": "^1.1.4", | ||
"@inquirer/core": "^5.0.1", | ||
"@inquirer/type": "^1.1.5", | ||
"ansi-escapes": "^4.3.2", | ||
@@ -68,3 +68,3 @@ "chalk": "^4.1.2", | ||
"devDependencies": { | ||
"@inquirer/testing": "^2.1.6" | ||
"@inquirer/testing": "^2.1.7" | ||
}, | ||
@@ -91,3 +91,3 @@ "scripts": { | ||
}, | ||
"gitHead": "c2d1c5fdfd1029f78351fb04e06f1cfb29d55bb6" | ||
"gitHead": "85784061d702778bc9dd48ca08f09ee9976b06ee" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
21041
356
Updated@inquirer/core@^5.0.1
Updated@inquirer/type@^1.1.5