inquirer-grouped-checkbox 0.1.0 → 0.2.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/theme.ts","../src/types.ts","../src/utils.ts"],"sourcesContent":["import {\n createPrompt,\n isBackspaceKey,\n isDownKey,\n isEnterKey,\n isSpaceKey,\n isTabKey,\n isUpKey,\n makeTheme,\n useKeypress,\n useMemo,\n usePagination,\n usePrefix,\n useRef,\n useState,\n type KeypressEvent,\n type Status,\n} from '@inquirer/core'\nimport { styleText } from 'node:util'\nimport { defaultTheme, type GroupedCheckboxTheme } from './theme.js'\nimport type { GroupedCheckboxConfig, GroupedSelections, Item, NormalizedChoice } from './types.js'\nimport { Separator } from './types.js'\nimport {\n buildSelections,\n filterBySearch,\n findFirstSelectableIndex,\n findNextSelectableIndex,\n getCurrentGroup,\n getGroupStats,\n isSelectableItem,\n normalizeGroups,\n} from './utils.js'\n\ninterface ExtendedKey extends KeypressEvent {\n shift?: boolean\n sequence?: string\n}\n\nconst groupedCheckbox = createPrompt(\n <Value>(config: GroupedCheckboxConfig<Value>, done: (value: GroupedSelections<Value>) => void) => {\n const { normalizedGroups: initialGroups, flatChoices: initialChoices } = useMemo(\n () => normalizeGroups(config.groups),\n [config.groups],\n )\n\n const [status, setStatus] = useState<Status>('idle')\n const [choices, setChoices] = useState<NormalizedChoice<Value>[]>(\n initialChoices.filter((item): item is NormalizedChoice<Value> => !Separator.isSeparator(item)),\n )\n const [searchQuery, setSearchQuery] = useState('')\n const [errorMessage, setErrorMessage] = useState<string | undefined>(undefined)\n const [cursorIndex, setCursorIndex] = useState(0)\n\n const theme = makeTheme<GroupedCheckboxTheme>(defaultTheme, config.theme?.checkbox)\n const prefix = usePrefix({ status, theme })\n\n const { filteredChoices, filteredGroups } = useMemo(\n () => filterBySearch(choices, initialGroups, searchQuery),\n [choices, initialGroups, searchQuery],\n )\n\n // Use ref to track current cursor for keypress handler\n const cursorRef = useRef(cursorIndex)\n cursorRef.current = cursorIndex\n\n const choicesRef = useRef(choices)\n choicesRef.current = choices\n\n const searchRef = useRef(searchQuery)\n searchRef.current = searchQuery\n\n const filteredChoicesRef = useRef(filteredChoices)\n filteredChoicesRef.current = filteredChoices\n\n const currentGroup = useMemo(() => getCurrentGroup(cursorIndex, filteredGroups), [cursorIndex, filteredGroups])\n\n const currentGroupRef = useRef(currentGroup)\n currentGroupRef.current = currentGroup\n\n useKeypress((event) => {\n const key = event as ExtendedKey\n if (status !== 'idle') return\n\n setErrorMessage(undefined)\n\n if (isEnterKey(key)) {\n const selections = buildSelections(choicesRef.current, initialGroups)\n\n if (config.required) {\n const hasSelection = Object.values(selections).some((arr) => arr.length > 0)\n if (!hasSelection) {\n setErrorMessage('At least one selection is required')\n return\n }\n }\n\n if (config.validate) {\n const result = config.validate(selections)\n if (result instanceof Promise) {\n setStatus('loading')\n result.then((validation) => {\n if (validation === true) {\n setStatus('done')\n done(selections)\n } else {\n setStatus('idle')\n setErrorMessage(typeof validation === 'string' ? validation : 'Invalid selection')\n }\n })\n return\n }\n if (result !== true) {\n setErrorMessage(typeof result === 'string' ? result : 'Invalid selection')\n return\n }\n }\n\n setStatus('done')\n done(selections)\n return\n }\n\n if (isUpKey(key)) {\n const newIndex = findNextSelectableIndex(filteredChoices, cursorRef.current, -1)\n setCursorIndex(newIndex)\n return\n }\n\n if (isDownKey(key)) {\n const newIndex = findNextSelectableIndex(filteredChoices, cursorRef.current, 1)\n setCursorIndex(newIndex)\n return\n }\n\n if (isSpaceKey(key)) {\n const currentItem = filteredChoices[cursorRef.current]\n if (currentItem && isSelectableItem(currentItem)) {\n const newChoices = choicesRef.current.map((choice) => {\n if (choice.value === currentItem.value && choice.groupKey === currentItem.groupKey) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n })\n setChoices(newChoices)\n }\n return\n }\n\n // Search input (when searchable) - handle first to capture alphanumeric keys\n if (config.searchable) {\n if (isBackspaceKey(key)) {\n setSearchQuery(searchRef.current.slice(0, -1))\n setCursorIndex(0)\n return\n }\n\n if (key.name === 'escape') {\n setSearchQuery('')\n setCursorIndex(findFirstSelectableIndex(choicesRef.current))\n return\n }\n\n // Alphanumeric input (except when Ctrl/Shift is held for shortcuts, or Tab)\n if (\n key.sequence &&\n !key.ctrl &&\n !key.shift &&\n !isTabKey(key) &&\n /^[a-zA-Z0-9\\-_./\\s]$/.test(key.sequence)\n ) {\n setSearchQuery(searchRef.current + key.sequence)\n setCursorIndex(0)\n return\n }\n }\n\n // Global toggle all: Ctrl+A (or 'a' when not searchable) - operates on filtered/visible choices only\n if ((key.name === 'a' && key.ctrl) || (key.name === 'a' && !key.shift && !config.searchable)) {\n const visibleChoices = filteredChoicesRef.current.filter(\n (c): c is NormalizedChoice<Value> => !Separator.isSeparator(c) && !c.disabled,\n )\n const allVisibleChecked = visibleChoices.every((c) => c.checked)\n const visibleValues = new Set(visibleChoices.map((c) => c.value))\n setChoices(\n choicesRef.current.map((choice) => {\n if (!choice.disabled && visibleValues.has(choice.value)) {\n return { ...choice, checked: !allVisibleChecked }\n }\n return choice\n }),\n )\n return\n }\n\n // Global invert: Ctrl+I (or 'i' when not searchable) - operates on filtered/visible choices only\n if ((key.name === 'i' && key.ctrl) || (key.name === 'i' && !key.shift && !config.searchable)) {\n const visibleChoices = filteredChoicesRef.current.filter(\n (c): c is NormalizedChoice<Value> => !Separator.isSeparator(c) && !c.disabled,\n )\n const visibleValues = new Set(visibleChoices.map((c) => c.value))\n setChoices(\n choicesRef.current.map((choice) => {\n if (!choice.disabled && visibleValues.has(choice.value)) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n }),\n )\n return\n }\n\n // Per-group toggle: 'A' (Shift+A) - operates on filtered/visible choices only\n if (key.name === 'a' && key.shift && currentGroupRef.current) {\n const group = currentGroupRef.current\n // Get visible choices in this group (filtered by search)\n const visibleGroupChoices = filteredChoicesRef.current.filter(\n (c): c is NormalizedChoice<Value> =>\n !Separator.isSeparator(c) && c.groupKey === group.key && !c.disabled,\n )\n const allVisibleChecked = visibleGroupChoices.every((c) => c.checked)\n const visibleValues = new Set(visibleGroupChoices.map((c) => c.value))\n // Toggle only the visible choices\n setChoices(\n choicesRef.current.map((choice) => {\n if (choice.groupKey === group.key && !choice.disabled && visibleValues.has(choice.value)) {\n return { ...choice, checked: !allVisibleChecked }\n }\n return choice\n }),\n )\n return\n }\n\n // Per-group invert: 'I' (Shift+I) - operates on filtered/visible choices only\n if (key.name === 'i' && key.shift && currentGroupRef.current) {\n const group = currentGroupRef.current\n // Get visible choices in this group (filtered by search)\n const visibleGroupChoices = filteredChoicesRef.current.filter(\n (c): c is NormalizedChoice<Value> =>\n !Separator.isSeparator(c) && c.groupKey === group.key && !c.disabled,\n )\n const visibleValues = new Set(visibleGroupChoices.map((c) => c.value))\n // Invert only the visible choices\n setChoices(\n choicesRef.current.map((choice) => {\n if (choice.groupKey === group.key && !choice.disabled && visibleValues.has(choice.value)) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n }),\n )\n return\n }\n\n // Tab: jump to next group\n if (isTabKey(key) && !key.shift) {\n if (currentGroupRef.current && filteredGroups.length > 1) {\n const currentGroupIdx = filteredGroups.findIndex((g) => g.key === currentGroupRef.current!.key)\n const nextGroupIdx = (currentGroupIdx + 1) % filteredGroups.length\n const nextGroup = filteredGroups[nextGroupIdx]\n if (nextGroup) {\n setCursorIndex(nextGroup.startIndex)\n }\n }\n return\n }\n\n // Shift+Tab: jump to previous group\n if (isTabKey(key) && key.shift) {\n if (currentGroupRef.current && filteredGroups.length > 1) {\n const currentGroupIdx = filteredGroups.findIndex((g) => g.key === currentGroupRef.current!.key)\n const prevGroupIdx = currentGroupIdx === 0 ? filteredGroups.length - 1 : currentGroupIdx - 1\n const prevGroup = filteredGroups[prevGroupIdx]\n if (prevGroup) {\n setCursorIndex(prevGroup.startIndex)\n }\n }\n return\n }\n })\n\n const page = usePagination<Item<Value>>({\n items: filteredChoices,\n active: cursorIndex,\n pageSize: config.pageSize ?? 15,\n renderItem: ({ item, index, isActive }) => {\n if (Separator.isSeparator(item)) {\n return ` ${item.separator}`\n }\n\n // Check if this is the first item in a group (render header)\n const group = filteredGroups.find((g) => g.startIndex === index)\n let header = ''\n if (group) {\n const stats = getGroupStats(group)\n const statsText = styleText('dim', ` (${stats.selected}/${stats.total})`)\n header = `\\n${theme.style.groupHeader(group.label, group.icon)}${statsText}\\n`\n }\n\n const checkbox = item.checked ? theme.icon.checked : theme.icon.unchecked\n const cursor = isActive ? theme.icon.cursor : ' '\n const color = item.checked ? theme.style.highlight : (text: string) => text\n const name = item.disabled\n ? theme.style.disabledChoice(\n `${item.name}${typeof item.disabled === 'string' ? ` (${item.disabled})` : ''}`,\n )\n : color(item.name)\n\n let line = `${header}${cursor} ${checkbox} ${name}`\n\n if (item.description && isActive) {\n line += `\\n ${theme.style.description(item.description)}`\n }\n\n return line\n },\n })\n\n // Build final output\n let message = config.message\n\n if (status === 'done') {\n const selections = buildSelections(choices, initialGroups)\n const totalSelected = Object.values(selections).reduce((sum, arr) => sum + arr.length, 0)\n message += styleText('cyan', ` ${totalSelected} item${totalSelected !== 1 ? 's' : ''} selected`)\n return `${prefix} ${message}`\n }\n\n let output = `${prefix} ${message}`\n\n if (config.searchable && searchQuery) {\n output += ` ${theme.style.searchQuery(`[${searchQuery}]`)}`\n }\n\n if (filteredChoices.length === 0) {\n output += `\\n${styleText('dim', ' No matches found')}`\n } else {\n output += `\\n${page}`\n }\n\n // Help text\n if (theme.helpMode === 'always' || (theme.helpMode === 'auto' && status === 'idle')) {\n const toggleKey = config.searchable ? 'ctrl+a' : 'a'\n const invertKey = config.searchable ? 'ctrl+i' : 'i'\n const helpText = [\n 'space: select',\n `${toggleKey}: toggle all`,\n `${invertKey}: invert`,\n config.searchable ? 'type to search' : '',\n ]\n .filter(Boolean)\n .join(', ')\n output += `\\n${styleText('dim', `(${helpText})`)}`\n }\n\n if (errorMessage) {\n output += `\\n${styleText('red', errorMessage)}`\n }\n\n return output\n },\n)\n\nexport default groupedCheckbox\nexport type { GroupedCheckboxTheme } from './theme.js'\nexport type {\n Choice,\n Group,\n GroupedCheckboxConfig,\n GroupedSelections,\n NormalizedChoice,\n NormalizedGroup,\n} from './types.js'\nexport { Separator }\n","import figures from '@inquirer/figures'\nimport { styleText } from 'node:util'\n\nexport interface GroupedCheckboxTheme {\n icon: {\n checked: string\n unchecked: string\n cursor: string\n }\n style: {\n disabledChoice: (text: string) => string\n groupHeader: (text: string, icon?: string) => string\n searchQuery: (text: string) => string\n highlight: (text: string) => string\n description: (text: string) => string\n }\n helpMode: 'always' | 'never' | 'auto'\n}\n\nexport const defaultTheme: GroupedCheckboxTheme = {\n icon: {\n checked: figures.circleFilled,\n unchecked: figures.circle,\n cursor: figures.pointer,\n },\n style: {\n disabledChoice: (text: string) => styleText('dim', text),\n groupHeader: (text: string, icon?: string) => styleText('bold', icon ? `${icon} ${text}` : text),\n searchQuery: (text: string) => styleText('cyan', text),\n highlight: (text: string) => styleText('cyan', text),\n description: (text: string) => styleText('dim', text),\n },\n helpMode: 'auto',\n}\n","import type { Theme } from '@inquirer/core'\nimport type { Prettify } from '@inquirer/type'\nimport type { GroupedCheckboxTheme } from './theme.js'\n\nexport interface Choice<Value> {\n value: Value\n name?: string\n description?: string\n short?: string\n disabled?: boolean | string\n checked?: boolean\n}\n\nexport interface Group<Value> {\n key: string\n label: string\n icon?: string\n choices: ReadonlyArray<Choice<Value>>\n}\n\nexport interface GroupedCheckboxConfig<Value> {\n message: string\n groups: ReadonlyArray<Group<Value>>\n searchable?: boolean\n pageSize?: number\n required?: boolean\n validate?: (selections: GroupedSelections<Value>) => boolean | string | Promise<boolean | string>\n theme?: PartialTheme\n}\n\nexport type PartialTheme = Prettify<Partial<Theme<GroupedCheckboxTheme>> & { checkbox?: Partial<GroupedCheckboxTheme> }>\n\nexport interface GroupedSelections<Value> {\n [groupKey: string]: Value[]\n}\n\nexport interface NormalizedChoice<Value> {\n value: Value\n name: string\n description?: string\n short: string\n disabled: boolean | string\n checked: boolean\n groupKey: string\n groupIndex: number\n indexInGroup: number\n}\n\nexport interface NormalizedGroup<Value> {\n key: string\n label: string\n icon?: string\n startIndex: number\n endIndex: number\n choices: NormalizedChoice<Value>[]\n}\n\nexport type Item<Value> = NormalizedChoice<Value> | Separator\n\nexport class Separator {\n readonly separator: string\n\n constructor(separator = '────────────────────') {\n this.separator = separator\n }\n\n static isSeparator(item: unknown): item is Separator {\n return item instanceof Separator\n }\n}\n","import type { Group, GroupedSelections, Item, NormalizedChoice, NormalizedGroup } from './types.js'\nimport { Separator } from './types.js'\n\nexport function normalizeGroups<Value>(groups: ReadonlyArray<Group<Value>>): {\n normalizedGroups: NormalizedGroup<Value>[]\n flatChoices: Item<Value>[]\n} {\n const normalizedGroups: NormalizedGroup<Value>[] = []\n const flatChoices: Item<Value>[] = []\n let flatIndex = 0\n\n groups.forEach((group, groupIndex) => {\n const startIndex = flatIndex\n const normalizedChoices: NormalizedChoice<Value>[] = []\n\n group.choices.forEach((choice, indexInGroup) => {\n const normalizedChoice: NormalizedChoice<Value> = {\n value: choice.value,\n name: choice.name ?? String(choice.value),\n description: choice.description,\n short: choice.short ?? choice.name ?? String(choice.value),\n disabled: choice.disabled ?? false,\n checked: choice.checked ?? false,\n groupKey: group.key,\n groupIndex,\n indexInGroup,\n }\n normalizedChoices.push(normalizedChoice)\n flatChoices.push(normalizedChoice)\n flatIndex++\n })\n\n normalizedGroups.push({\n key: group.key,\n label: group.label,\n icon: group.icon,\n startIndex,\n endIndex: flatIndex - 1,\n choices: normalizedChoices,\n })\n })\n\n return { normalizedGroups, flatChoices }\n}\n\nexport function filterBySearch<Value>(\n flatChoices: Item<Value>[],\n groups: NormalizedGroup<Value>[],\n query: string,\n): {\n filteredChoices: Item<Value>[]\n filteredGroups: NormalizedGroup<Value>[]\n} {\n if (!query) {\n return { filteredChoices: flatChoices, filteredGroups: groups }\n }\n\n const lowerQuery = query.toLowerCase()\n const filteredChoices: Item<Value>[] = []\n const filteredGroups: NormalizedGroup<Value>[] = []\n let flatIndex = 0\n\n for (const group of groups) {\n const matchingChoices: NormalizedChoice<Value>[] = []\n const startIndex = flatIndex\n\n // Use flatChoices (current state) filtered by groupKey, not group.choices (stale)\n const currentGroupChoices = flatChoices.filter(\n (c): c is NormalizedChoice<Value> => !Separator.isSeparator(c) && c.groupKey === group.key,\n )\n\n for (const choice of currentGroupChoices) {\n if (choice.name.toLowerCase().includes(lowerQuery)) {\n matchingChoices.push(choice)\n filteredChoices.push(choice)\n flatIndex++\n }\n }\n\n if (matchingChoices.length > 0) {\n filteredGroups.push({\n ...group,\n startIndex,\n endIndex: flatIndex - 1,\n choices: matchingChoices,\n })\n }\n }\n\n return { filteredChoices, filteredGroups }\n}\n\nexport function getCurrentGroup<Value>(\n cursorIndex: number,\n groups: NormalizedGroup<Value>[],\n): NormalizedGroup<Value> | undefined {\n return groups.find((group) => cursorIndex >= group.startIndex && cursorIndex <= group.endIndex)\n}\n\nexport function getSelectableInGroup<Value>(group: NormalizedGroup<Value>): NormalizedChoice<Value>[] {\n return group.choices.filter((choice) => !choice.disabled)\n}\n\nexport function toggleGroup<Value>(\n choices: NormalizedChoice<Value>[],\n group: NormalizedGroup<Value>,\n checked: boolean,\n): NormalizedChoice<Value>[] {\n return choices.map((choice) => {\n if (choice.groupKey === group.key && !choice.disabled) {\n return { ...choice, checked }\n }\n return choice\n })\n}\n\nexport function invertGroup<Value>(\n choices: NormalizedChoice<Value>[],\n group: NormalizedGroup<Value>,\n): NormalizedChoice<Value>[] {\n return choices.map((choice) => {\n if (choice.groupKey === group.key && !choice.disabled) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n })\n}\n\nexport function toggleAll<Value>(choices: NormalizedChoice<Value>[], checked: boolean): NormalizedChoice<Value>[] {\n return choices.map((choice) => {\n if (!choice.disabled) {\n return { ...choice, checked }\n }\n return choice\n })\n}\n\nexport function invertAll<Value>(choices: NormalizedChoice<Value>[]): NormalizedChoice<Value>[] {\n return choices.map((choice) => {\n if (!choice.disabled) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n })\n}\n\nexport function buildSelections<Value>(\n choices: NormalizedChoice<Value>[],\n groups: NormalizedGroup<Value>[],\n): GroupedSelections<Value> {\n const selections: GroupedSelections<Value> = {}\n\n for (const group of groups) {\n selections[group.key] = []\n }\n\n for (const choice of choices) {\n if (choice.checked) {\n const groupSelections = selections[choice.groupKey]\n if (groupSelections) {\n groupSelections.push(choice.value)\n }\n }\n }\n\n return selections\n}\n\nexport function isSelectableItem<Value>(item: Item<Value>): item is NormalizedChoice<Value> {\n return !Separator.isSeparator(item) && !item.disabled\n}\n\nexport function findNextSelectableIndex<Value>(items: Item<Value>[], currentIndex: number, direction: 1 | -1): number {\n const length = items.length\n if (length === 0) return -1\n\n let index = currentIndex + direction\n let iterations = 0\n\n while (iterations < length) {\n if (index < 0) index = length - 1\n if (index >= length) index = 0\n\n const item = items[index]\n if (item && isSelectableItem(item)) {\n return index\n }\n\n index += direction\n iterations++\n }\n\n return currentIndex\n}\n\nexport function findFirstSelectableIndex<Value>(items: Item<Value>[]): number {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n if (item && isSelectableItem(item)) {\n return i\n }\n }\n return 0\n}\n\nexport function getGroupStats<Value>(group: NormalizedGroup<Value>): { selected: number; total: number } {\n const selectable = getSelectableInGroup(group)\n const selected = selectable.filter((c) => c.checked).length\n return { selected, total: selectable.length }\n}\n"],"mappings":"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","names":["import_node_util","figures"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/theme.ts","../src/types.ts","../src/utils.ts"],"sourcesContent":["import {\n createPrompt,\n isBackspaceKey,\n isDownKey,\n isEnterKey,\n isSpaceKey,\n isTabKey,\n isUpKey,\n makeTheme,\n useKeypress,\n useMemo,\n usePagination,\n usePrefix,\n useRef,\n useState,\n type KeypressEvent,\n type Status,\n} from '@inquirer/core'\nimport type { Context } from '@inquirer/type'\nimport { styleText } from 'node:util'\nimport { defaultTheme, type GroupedCheckboxTheme } from './theme.js'\nimport type { GroupedCheckboxConfig, GroupedSelections, Item, NormalizedChoice } from './types.js'\nimport { Separator } from './types.js'\nimport {\n buildSelections,\n filterBySearch,\n findFirstSelectableIndex,\n findNextSelectableIndex,\n getCurrentGroup,\n getGroupStats,\n isSelectableItem,\n normalizeGroups,\n} from './utils.js'\n\ninterface ExtendedKey extends KeypressEvent {\n shift: boolean\n sequence?: string\n}\n\nconst groupedCheckbox: <Value>(\n config: GroupedCheckboxConfig<Value>,\n context?: Context,\n) => Promise<GroupedSelections<Value>> = createPrompt(\n <Value>(config: GroupedCheckboxConfig<Value>, done: (value: GroupedSelections<Value>) => void) => {\n const { normalizedGroups: initialGroups, flatChoices: initialChoices } = useMemo(\n () => normalizeGroups(config.groups),\n [config.groups],\n )\n\n const [status, setStatus] = useState<Status>('idle')\n const [choices, setChoices] = useState<NormalizedChoice<Value>[]>(\n initialChoices.filter((item): item is NormalizedChoice<Value> => !Separator.isSeparator(item)),\n )\n const [searchQuery, setSearchQuery] = useState('')\n const [errorMessage, setErrorMessage] = useState<string | undefined>(undefined)\n const [cursorIndex, setCursorIndex] = useState(0)\n\n const theme = makeTheme<GroupedCheckboxTheme>(defaultTheme, config.theme?.checkbox)\n const prefix = usePrefix({ status, theme })\n\n const { filteredChoices, filteredGroups } = useMemo(\n () => filterBySearch(choices, initialGroups, searchQuery),\n [choices, initialGroups, searchQuery],\n )\n\n // Use ref to track current cursor for keypress handler\n const cursorRef = useRef(cursorIndex)\n cursorRef.current = cursorIndex\n\n const choicesRef = useRef(choices)\n choicesRef.current = choices\n\n const searchRef = useRef(searchQuery)\n searchRef.current = searchQuery\n\n const filteredChoicesRef = useRef(filteredChoices)\n filteredChoicesRef.current = filteredChoices\n\n const currentGroup = useMemo(() => getCurrentGroup(cursorIndex, filteredGroups), [cursorIndex, filteredGroups])\n\n const currentGroupRef = useRef(currentGroup)\n currentGroupRef.current = currentGroup\n\n useKeypress((event) => {\n const key = event as ExtendedKey\n if (status !== 'idle') return\n\n setErrorMessage(undefined)\n\n if (isEnterKey(key)) {\n const selections = buildSelections(choicesRef.current, initialGroups)\n\n if (config.required) {\n const hasSelection = Object.values(selections).some((arr) => arr.length > 0)\n if (!hasSelection) {\n setErrorMessage('At least one selection is required')\n return\n }\n }\n\n if (config.validate) {\n const result = config.validate(selections)\n if (result instanceof Promise) {\n setStatus('loading')\n result.then((validation) => {\n if (validation === true) {\n setStatus('done')\n done(selections)\n } else {\n setStatus('idle')\n setErrorMessage(typeof validation === 'string' ? validation : 'Invalid selection')\n }\n })\n return\n }\n if (result !== true) {\n setErrorMessage(typeof result === 'string' ? result : 'Invalid selection')\n return\n }\n }\n\n setStatus('done')\n done(selections)\n return\n }\n\n if (isUpKey(key)) {\n const newIndex = findNextSelectableIndex(filteredChoices, cursorRef.current, -1)\n setCursorIndex(newIndex)\n return\n }\n\n if (isDownKey(key)) {\n const newIndex = findNextSelectableIndex(filteredChoices, cursorRef.current, 1)\n setCursorIndex(newIndex)\n return\n }\n\n if (isSpaceKey(key)) {\n const currentItem = filteredChoices[cursorRef.current]\n if (currentItem && isSelectableItem(currentItem)) {\n const newChoices = choicesRef.current.map((choice) => {\n if (choice.value === currentItem.value && choice.groupKey === currentItem.groupKey) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n })\n setChoices(newChoices)\n }\n return\n }\n\n // Search input (when searchable) - handle first to capture alphanumeric keys\n if (config.searchable) {\n if (isBackspaceKey(key)) {\n setSearchQuery(searchRef.current.slice(0, -1))\n setCursorIndex(0)\n return\n }\n\n if (key.name === 'escape') {\n setSearchQuery('')\n setCursorIndex(findFirstSelectableIndex(choicesRef.current))\n return\n }\n\n // Alphanumeric input (except when Ctrl/Shift is held for shortcuts, or Tab)\n if (\n key.sequence &&\n !key.ctrl &&\n !key.shift &&\n !isTabKey(key) &&\n /^[a-zA-Z0-9\\-_./\\s]$/.test(key.sequence)\n ) {\n setSearchQuery(searchRef.current + key.sequence)\n setCursorIndex(0)\n return\n }\n }\n\n // Global toggle all: Ctrl+A (or 'a' when not searchable) - operates on filtered/visible choices only\n if ((key.name === 'a' && key.ctrl) || (key.name === 'a' && !key.shift && !config.searchable)) {\n const visibleChoices = filteredChoicesRef.current.filter(\n (c): c is NormalizedChoice<Value> => !Separator.isSeparator(c) && !c.disabled,\n )\n const allVisibleChecked = visibleChoices.every((c) => c.checked)\n const visibleValues = new Set(visibleChoices.map((c) => c.value))\n setChoices(\n choicesRef.current.map((choice) => {\n if (!choice.disabled && visibleValues.has(choice.value)) {\n return { ...choice, checked: !allVisibleChecked }\n }\n return choice\n }),\n )\n return\n }\n\n // Global invert: Ctrl+I (or 'i' when not searchable) - operates on filtered/visible choices only\n if ((key.name === 'i' && key.ctrl) || (key.name === 'i' && !key.shift && !config.searchable)) {\n const visibleChoices = filteredChoicesRef.current.filter(\n (c): c is NormalizedChoice<Value> => !Separator.isSeparator(c) && !c.disabled,\n )\n const visibleValues = new Set(visibleChoices.map((c) => c.value))\n setChoices(\n choicesRef.current.map((choice) => {\n if (!choice.disabled && visibleValues.has(choice.value)) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n }),\n )\n return\n }\n\n // Per-group toggle: 'A' (Shift+A) - operates on filtered/visible choices only\n if (key.name === 'a' && key.shift && currentGroupRef.current) {\n const group = currentGroupRef.current\n // Get visible choices in this group (filtered by search)\n const visibleGroupChoices = filteredChoicesRef.current.filter(\n (c): c is NormalizedChoice<Value> =>\n !Separator.isSeparator(c) && c.groupKey === group.key && !c.disabled,\n )\n const allVisibleChecked = visibleGroupChoices.every((c) => c.checked)\n const visibleValues = new Set(visibleGroupChoices.map((c) => c.value))\n // Toggle only the visible choices\n setChoices(\n choicesRef.current.map((choice) => {\n if (choice.groupKey === group.key && !choice.disabled && visibleValues.has(choice.value)) {\n return { ...choice, checked: !allVisibleChecked }\n }\n return choice\n }),\n )\n return\n }\n\n // Per-group invert: 'I' (Shift+I) - operates on filtered/visible choices only\n if (key.name === 'i' && key.shift && currentGroupRef.current) {\n const group = currentGroupRef.current\n // Get visible choices in this group (filtered by search)\n const visibleGroupChoices = filteredChoicesRef.current.filter(\n (c): c is NormalizedChoice<Value> =>\n !Separator.isSeparator(c) && c.groupKey === group.key && !c.disabled,\n )\n const visibleValues = new Set(visibleGroupChoices.map((c) => c.value))\n // Invert only the visible choices\n setChoices(\n choicesRef.current.map((choice) => {\n if (choice.groupKey === group.key && !choice.disabled && visibleValues.has(choice.value)) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n }),\n )\n return\n }\n\n // Tab: jump to next group\n if (isTabKey(key) && !key.shift) {\n if (currentGroupRef.current && filteredGroups.length > 1) {\n const currentGroupIdx = filteredGroups.findIndex((g) => g.key === currentGroupRef.current!.key)\n const nextGroupIdx = (currentGroupIdx + 1) % filteredGroups.length\n const nextGroup = filteredGroups[nextGroupIdx]\n if (nextGroup) {\n setCursorIndex(nextGroup.startIndex)\n }\n }\n return\n }\n\n // Shift+Tab: jump to previous group\n if (isTabKey(key) && key.shift) {\n if (currentGroupRef.current && filteredGroups.length > 1) {\n const currentGroupIdx = filteredGroups.findIndex((g) => g.key === currentGroupRef.current!.key)\n const prevGroupIdx = currentGroupIdx === 0 ? filteredGroups.length - 1 : currentGroupIdx - 1\n const prevGroup = filteredGroups[prevGroupIdx]\n if (prevGroup) {\n setCursorIndex(prevGroup.startIndex)\n }\n }\n return\n }\n })\n\n const page = usePagination<Item<Value>>({\n items: filteredChoices,\n active: cursorIndex,\n pageSize: config.pageSize ?? 15,\n renderItem: ({ item, index, isActive }) => {\n if (Separator.isSeparator(item)) {\n return ` ${item.separator}`\n }\n\n // Check if this is the first item in a group (render header)\n const group = filteredGroups.find((g) => g.startIndex === index)\n let header = ''\n if (group) {\n const stats = getGroupStats(group)\n const statsText = styleText('dim', ` (${stats.selected}/${stats.total})`)\n header = `\\n${theme.style.groupHeader(group.label, group.icon)}${statsText}\\n`\n }\n\n const checkbox = item.checked ? theme.icon.checked : theme.icon.unchecked\n const cursor = isActive ? theme.icon.cursor : ' '\n const color = item.checked ? theme.style.highlight : (text: string) => text\n const name = item.disabled\n ? theme.style.disabledChoice(\n `${item.name}${typeof item.disabled === 'string' ? ` (${item.disabled})` : ''}`,\n )\n : color(item.name)\n\n let line = `${header}${cursor} ${checkbox} ${name}`\n\n if (item.description && isActive) {\n line += `\\n ${theme.style.description(item.description)}`\n }\n\n return line\n },\n })\n\n // Build final output\n let message = config.message\n\n if (status === 'done') {\n const selections = buildSelections(choices, initialGroups)\n const totalSelected = Object.values(selections).reduce((sum, arr) => sum + arr.length, 0)\n message += styleText('cyan', ` ${totalSelected} item${totalSelected !== 1 ? 's' : ''} selected`)\n return `${prefix} ${message}`\n }\n\n let output = `${prefix} ${message}`\n\n if (config.searchable && searchQuery) {\n output += ` ${theme.style.searchQuery(`[${searchQuery}]`)}`\n }\n\n if (filteredChoices.length === 0) {\n output += `\\n${styleText('dim', ' No matches found')}`\n } else {\n output += `\\n${page}`\n }\n\n // Help text\n if (theme.helpMode === 'always' || (theme.helpMode === 'auto' && status === 'idle')) {\n const toggleKey = config.searchable ? 'ctrl+a' : 'a'\n const invertKey = config.searchable ? 'ctrl+i' : 'i'\n const helpText = [\n 'space: select',\n `${toggleKey}: toggle all`,\n `${invertKey}: invert`,\n config.searchable ? 'type to search' : '',\n ]\n .filter(Boolean)\n .join(', ')\n output += `\\n${styleText('dim', `(${helpText})`)}`\n }\n\n if (errorMessage) {\n output += `\\n${styleText('red', errorMessage)}`\n }\n\n return output\n },\n)\n\nexport default groupedCheckbox\nexport type { GroupedCheckboxTheme } from './theme.js'\nexport type {\n Choice,\n Group,\n GroupedCheckboxConfig,\n GroupedSelections,\n NormalizedChoice,\n NormalizedGroup,\n} from './types.js'\nexport { Separator }\n","import figures from '@inquirer/figures'\nimport { styleText } from 'node:util'\n\nexport interface GroupedCheckboxTheme {\n icon: {\n checked: string\n unchecked: string\n cursor: string\n }\n style: {\n disabledChoice: (text: string) => string\n groupHeader: (text: string, icon?: string) => string\n searchQuery: (text: string) => string\n highlight: (text: string) => string\n description: (text: string) => string\n }\n helpMode: 'always' | 'never' | 'auto'\n}\n\nexport const defaultTheme: GroupedCheckboxTheme = {\n icon: {\n checked: figures.circleFilled,\n unchecked: figures.circle,\n cursor: figures.pointer,\n },\n style: {\n disabledChoice: (text: string) => styleText('dim', text),\n groupHeader: (text: string, icon?: string) => styleText('bold', icon ? `${icon} ${text}` : text),\n searchQuery: (text: string) => styleText('cyan', text),\n highlight: (text: string) => styleText('cyan', text),\n description: (text: string) => styleText('dim', text),\n },\n helpMode: 'auto',\n}\n","import type { Theme } from '@inquirer/core'\nimport type { Prettify } from '@inquirer/type'\nimport type { GroupedCheckboxTheme } from './theme.js'\n\nexport interface Choice<Value> {\n value: Value\n name?: string\n description?: string\n short?: string\n disabled?: boolean | string\n checked?: boolean\n}\n\nexport interface Group<Value> {\n key: string\n label: string\n icon?: string\n choices: ReadonlyArray<Choice<Value>>\n}\n\nexport interface GroupedCheckboxConfig<Value> {\n message: string\n groups: ReadonlyArray<Group<Value>>\n searchable?: boolean\n pageSize?: number\n required?: boolean\n validate?: (selections: GroupedSelections<Value>) => boolean | string | Promise<boolean | string>\n theme?: PartialTheme\n}\n\nexport type PartialTheme = Prettify<Partial<Theme<GroupedCheckboxTheme>> & { checkbox?: Partial<GroupedCheckboxTheme> }>\n\nexport interface GroupedSelections<Value> {\n [groupKey: string]: Value[]\n}\n\nexport interface NormalizedChoice<Value> {\n value: Value\n name: string\n description?: string\n short: string\n disabled: boolean | string\n checked: boolean\n groupKey: string\n groupIndex: number\n indexInGroup: number\n}\n\nexport interface NormalizedGroup<Value> {\n key: string\n label: string\n icon?: string\n startIndex: number\n endIndex: number\n choices: NormalizedChoice<Value>[]\n}\n\nexport type Item<Value> = NormalizedChoice<Value> | Separator\n\nexport class Separator {\n readonly separator: string\n\n constructor(separator = '────────────────────') {\n this.separator = separator\n }\n\n static isSeparator(item: unknown): item is Separator {\n return item instanceof Separator\n }\n}\n","import type { Group, GroupedSelections, Item, NormalizedChoice, NormalizedGroup } from './types.js'\nimport { Separator } from './types.js'\n\nexport function normalizeGroups<Value>(groups: ReadonlyArray<Group<Value>>): {\n normalizedGroups: NormalizedGroup<Value>[]\n flatChoices: Item<Value>[]\n} {\n const normalizedGroups: NormalizedGroup<Value>[] = []\n const flatChoices: Item<Value>[] = []\n let flatIndex = 0\n\n groups.forEach((group, groupIndex) => {\n const startIndex = flatIndex\n const normalizedChoices: NormalizedChoice<Value>[] = []\n\n group.choices.forEach((choice, indexInGroup) => {\n const normalizedChoice: NormalizedChoice<Value> = {\n value: choice.value,\n name: choice.name ?? String(choice.value),\n description: choice.description,\n short: choice.short ?? choice.name ?? String(choice.value),\n disabled: choice.disabled ?? false,\n checked: choice.checked ?? false,\n groupKey: group.key,\n groupIndex,\n indexInGroup,\n }\n normalizedChoices.push(normalizedChoice)\n flatChoices.push(normalizedChoice)\n flatIndex++\n })\n\n normalizedGroups.push({\n key: group.key,\n label: group.label,\n icon: group.icon,\n startIndex,\n endIndex: flatIndex - 1,\n choices: normalizedChoices,\n })\n })\n\n return { normalizedGroups, flatChoices }\n}\n\nexport function filterBySearch<Value>(\n flatChoices: Item<Value>[],\n groups: NormalizedGroup<Value>[],\n query: string,\n): {\n filteredChoices: Item<Value>[]\n filteredGroups: NormalizedGroup<Value>[]\n} {\n if (!query) {\n return { filteredChoices: flatChoices, filteredGroups: groups }\n }\n\n const lowerQuery = query.toLowerCase()\n const filteredChoices: Item<Value>[] = []\n const filteredGroups: NormalizedGroup<Value>[] = []\n let flatIndex = 0\n\n for (const group of groups) {\n const matchingChoices: NormalizedChoice<Value>[] = []\n const startIndex = flatIndex\n\n // Use flatChoices (current state) filtered by groupKey, not group.choices (stale)\n const currentGroupChoices = flatChoices.filter(\n (c): c is NormalizedChoice<Value> => !Separator.isSeparator(c) && c.groupKey === group.key,\n )\n\n for (const choice of currentGroupChoices) {\n if (choice.name.toLowerCase().includes(lowerQuery)) {\n matchingChoices.push(choice)\n filteredChoices.push(choice)\n flatIndex++\n }\n }\n\n if (matchingChoices.length > 0) {\n filteredGroups.push({\n ...group,\n startIndex,\n endIndex: flatIndex - 1,\n choices: matchingChoices,\n })\n }\n }\n\n return { filteredChoices, filteredGroups }\n}\n\nexport function getCurrentGroup<Value>(\n cursorIndex: number,\n groups: NormalizedGroup<Value>[],\n): NormalizedGroup<Value> | undefined {\n return groups.find((group) => cursorIndex >= group.startIndex && cursorIndex <= group.endIndex)\n}\n\nexport function getSelectableInGroup<Value>(group: NormalizedGroup<Value>): NormalizedChoice<Value>[] {\n return group.choices.filter((choice) => !choice.disabled)\n}\n\nexport function toggleGroup<Value>(\n choices: NormalizedChoice<Value>[],\n group: NormalizedGroup<Value>,\n checked: boolean,\n): NormalizedChoice<Value>[] {\n return choices.map((choice) => {\n if (choice.groupKey === group.key && !choice.disabled) {\n return { ...choice, checked }\n }\n return choice\n })\n}\n\nexport function invertGroup<Value>(\n choices: NormalizedChoice<Value>[],\n group: NormalizedGroup<Value>,\n): NormalizedChoice<Value>[] {\n return choices.map((choice) => {\n if (choice.groupKey === group.key && !choice.disabled) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n })\n}\n\nexport function toggleAll<Value>(choices: NormalizedChoice<Value>[], checked: boolean): NormalizedChoice<Value>[] {\n return choices.map((choice) => {\n if (!choice.disabled) {\n return { ...choice, checked }\n }\n return choice\n })\n}\n\nexport function invertAll<Value>(choices: NormalizedChoice<Value>[]): NormalizedChoice<Value>[] {\n return choices.map((choice) => {\n if (!choice.disabled) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n })\n}\n\nexport function buildSelections<Value>(\n choices: NormalizedChoice<Value>[],\n groups: NormalizedGroup<Value>[],\n): GroupedSelections<Value> {\n const selections: GroupedSelections<Value> = {}\n\n for (const group of groups) {\n selections[group.key] = []\n }\n\n for (const choice of choices) {\n if (choice.checked) {\n const groupSelections = selections[choice.groupKey]\n if (groupSelections) {\n groupSelections.push(choice.value)\n }\n }\n }\n\n return selections\n}\n\nexport function isSelectableItem<Value>(item: Item<Value>): item is NormalizedChoice<Value> {\n return !Separator.isSeparator(item) && !item.disabled\n}\n\nexport function findNextSelectableIndex<Value>(items: Item<Value>[], currentIndex: number, direction: 1 | -1): number {\n const length = items.length\n if (length === 0) return -1\n\n let index = currentIndex + direction\n let iterations = 0\n\n while (iterations < length) {\n if (index < 0) index = length - 1\n if (index >= length) index = 0\n\n const item = items[index]\n if (item && isSelectableItem(item)) {\n return index\n }\n\n index += direction\n iterations++\n }\n\n return currentIndex\n}\n\nexport function findFirstSelectableIndex<Value>(items: Item<Value>[]): number {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n if (item && isSelectableItem(item)) {\n return i\n }\n }\n return 0\n}\n\nexport function getGroupStats<Value>(group: NormalizedGroup<Value>): { selected: number; total: number } {\n const selectable = getSelectableInGroup(group)\n const selected = selectable.filter((c) => c.checked).length\n return { selected, total: selectable.length }\n}\n"],"mappings":"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","names":["import_node_util","figures"]}
package/dist/index.d.cts CHANGED
@@ -1,6 +1,5 @@
1
- import * as _inquirer_type from '@inquirer/type';
2
- import { Prettify } from '@inquirer/type';
3
- import { Theme, Status } from '@inquirer/core';
1
+ import { Prettify, Context } from '@inquirer/type';
2
+ import { Theme } from '@inquirer/core';
4
3
 
5
4
  interface GroupedCheckboxTheme {
6
5
  icon: {
@@ -72,48 +71,6 @@ declare class Separator {
72
71
  static isSeparator(item: unknown): item is Separator;
73
72
  }
74
73
 
75
- declare const groupedCheckbox: <Value>(config: {
76
- message: string;
77
- groups: readonly Group<Value>[];
78
- searchable?: boolean | undefined;
79
- pageSize?: number | undefined;
80
- required?: boolean | undefined;
81
- validate?: ((selections: GroupedSelections<Value>) => boolean | string | Promise<boolean | string>) | undefined;
82
- theme?: {
83
- icon?: {
84
- checked: string;
85
- unchecked: string;
86
- cursor: string;
87
- } | undefined;
88
- style?: ({
89
- disabledChoice: (text: string) => string;
90
- groupHeader: (text: string, icon?: string) => string;
91
- searchQuery: (text: string) => string;
92
- highlight: (text: string) => string;
93
- description: (text: string) => string;
94
- } & {
95
- answer: (text: string) => string;
96
- message: (text: string, status: Status) => string;
97
- error: (text: string) => string;
98
- defaultAnswer: (text: string) => string;
99
- help: (text: string) => string;
100
- highlight: (text: string) => string;
101
- key: (text: string) => string;
102
- }) | undefined;
103
- helpMode?: "always" | "never" | "auto" | undefined;
104
- prefix?: string | {
105
- [x: string & {}]: string;
106
- idle: string;
107
- done: string;
108
- } | undefined;
109
- spinner?: {
110
- interval: number;
111
- frames: string[];
112
- } | undefined;
113
- checkbox?: Partial<GroupedCheckboxTheme> | undefined;
114
- } | undefined;
115
- }, context?: _inquirer_type.Context) => Promise<GroupedSelections<Value>> & {
116
- cancel: () => void;
117
- };
74
+ declare const groupedCheckbox: <Value>(config: GroupedCheckboxConfig<Value>, context?: Context) => Promise<GroupedSelections<Value>>;
118
75
 
119
76
  export { type Choice, type Group, type GroupedCheckboxConfig, type GroupedCheckboxTheme, type GroupedSelections, type NormalizedChoice, type NormalizedGroup, Separator, groupedCheckbox as default };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,5 @@
1
- import * as _inquirer_type from '@inquirer/type';
2
- import { Prettify } from '@inquirer/type';
3
- import { Theme, Status } from '@inquirer/core';
1
+ import { Prettify, Context } from '@inquirer/type';
2
+ import { Theme } from '@inquirer/core';
4
3
 
5
4
  interface GroupedCheckboxTheme {
6
5
  icon: {
@@ -72,48 +71,6 @@ declare class Separator {
72
71
  static isSeparator(item: unknown): item is Separator;
73
72
  }
74
73
 
75
- declare const groupedCheckbox: <Value>(config: {
76
- message: string;
77
- groups: readonly Group<Value>[];
78
- searchable?: boolean | undefined;
79
- pageSize?: number | undefined;
80
- required?: boolean | undefined;
81
- validate?: ((selections: GroupedSelections<Value>) => boolean | string | Promise<boolean | string>) | undefined;
82
- theme?: {
83
- icon?: {
84
- checked: string;
85
- unchecked: string;
86
- cursor: string;
87
- } | undefined;
88
- style?: ({
89
- disabledChoice: (text: string) => string;
90
- groupHeader: (text: string, icon?: string) => string;
91
- searchQuery: (text: string) => string;
92
- highlight: (text: string) => string;
93
- description: (text: string) => string;
94
- } & {
95
- answer: (text: string) => string;
96
- message: (text: string, status: Status) => string;
97
- error: (text: string) => string;
98
- defaultAnswer: (text: string) => string;
99
- help: (text: string) => string;
100
- highlight: (text: string) => string;
101
- key: (text: string) => string;
102
- }) | undefined;
103
- helpMode?: "always" | "never" | "auto" | undefined;
104
- prefix?: string | {
105
- [x: string & {}]: string;
106
- idle: string;
107
- done: string;
108
- } | undefined;
109
- spinner?: {
110
- interval: number;
111
- frames: string[];
112
- } | undefined;
113
- checkbox?: Partial<GroupedCheckboxTheme> | undefined;
114
- } | undefined;
115
- }, context?: _inquirer_type.Context) => Promise<GroupedSelections<Value>> & {
116
- cancel: () => void;
117
- };
74
+ declare const groupedCheckbox: <Value>(config: GroupedCheckboxConfig<Value>, context?: Context) => Promise<GroupedSelections<Value>>;
118
75
 
119
76
  export { type Choice, type Group, type GroupedCheckboxConfig, type GroupedCheckboxTheme, type GroupedSelections, type NormalizedChoice, type NormalizedGroup, Separator, groupedCheckbox as default };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/theme.ts","../src/types.ts","../src/utils.ts"],"sourcesContent":["import {\n createPrompt,\n isBackspaceKey,\n isDownKey,\n isEnterKey,\n isSpaceKey,\n isTabKey,\n isUpKey,\n makeTheme,\n useKeypress,\n useMemo,\n usePagination,\n usePrefix,\n useRef,\n useState,\n type KeypressEvent,\n type Status,\n} from '@inquirer/core'\nimport { styleText } from 'node:util'\nimport { defaultTheme, type GroupedCheckboxTheme } from './theme.js'\nimport type { GroupedCheckboxConfig, GroupedSelections, Item, NormalizedChoice } from './types.js'\nimport { Separator } from './types.js'\nimport {\n buildSelections,\n filterBySearch,\n findFirstSelectableIndex,\n findNextSelectableIndex,\n getCurrentGroup,\n getGroupStats,\n isSelectableItem,\n normalizeGroups,\n} from './utils.js'\n\ninterface ExtendedKey extends KeypressEvent {\n shift?: boolean\n sequence?: string\n}\n\nconst groupedCheckbox = createPrompt(\n <Value>(config: GroupedCheckboxConfig<Value>, done: (value: GroupedSelections<Value>) => void) => {\n const { normalizedGroups: initialGroups, flatChoices: initialChoices } = useMemo(\n () => normalizeGroups(config.groups),\n [config.groups],\n )\n\n const [status, setStatus] = useState<Status>('idle')\n const [choices, setChoices] = useState<NormalizedChoice<Value>[]>(\n initialChoices.filter((item): item is NormalizedChoice<Value> => !Separator.isSeparator(item)),\n )\n const [searchQuery, setSearchQuery] = useState('')\n const [errorMessage, setErrorMessage] = useState<string | undefined>(undefined)\n const [cursorIndex, setCursorIndex] = useState(0)\n\n const theme = makeTheme<GroupedCheckboxTheme>(defaultTheme, config.theme?.checkbox)\n const prefix = usePrefix({ status, theme })\n\n const { filteredChoices, filteredGroups } = useMemo(\n () => filterBySearch(choices, initialGroups, searchQuery),\n [choices, initialGroups, searchQuery],\n )\n\n // Use ref to track current cursor for keypress handler\n const cursorRef = useRef(cursorIndex)\n cursorRef.current = cursorIndex\n\n const choicesRef = useRef(choices)\n choicesRef.current = choices\n\n const searchRef = useRef(searchQuery)\n searchRef.current = searchQuery\n\n const filteredChoicesRef = useRef(filteredChoices)\n filteredChoicesRef.current = filteredChoices\n\n const currentGroup = useMemo(() => getCurrentGroup(cursorIndex, filteredGroups), [cursorIndex, filteredGroups])\n\n const currentGroupRef = useRef(currentGroup)\n currentGroupRef.current = currentGroup\n\n useKeypress((event) => {\n const key = event as ExtendedKey\n if (status !== 'idle') return\n\n setErrorMessage(undefined)\n\n if (isEnterKey(key)) {\n const selections = buildSelections(choicesRef.current, initialGroups)\n\n if (config.required) {\n const hasSelection = Object.values(selections).some((arr) => arr.length > 0)\n if (!hasSelection) {\n setErrorMessage('At least one selection is required')\n return\n }\n }\n\n if (config.validate) {\n const result = config.validate(selections)\n if (result instanceof Promise) {\n setStatus('loading')\n result.then((validation) => {\n if (validation === true) {\n setStatus('done')\n done(selections)\n } else {\n setStatus('idle')\n setErrorMessage(typeof validation === 'string' ? validation : 'Invalid selection')\n }\n })\n return\n }\n if (result !== true) {\n setErrorMessage(typeof result === 'string' ? result : 'Invalid selection')\n return\n }\n }\n\n setStatus('done')\n done(selections)\n return\n }\n\n if (isUpKey(key)) {\n const newIndex = findNextSelectableIndex(filteredChoices, cursorRef.current, -1)\n setCursorIndex(newIndex)\n return\n }\n\n if (isDownKey(key)) {\n const newIndex = findNextSelectableIndex(filteredChoices, cursorRef.current, 1)\n setCursorIndex(newIndex)\n return\n }\n\n if (isSpaceKey(key)) {\n const currentItem = filteredChoices[cursorRef.current]\n if (currentItem && isSelectableItem(currentItem)) {\n const newChoices = choicesRef.current.map((choice) => {\n if (choice.value === currentItem.value && choice.groupKey === currentItem.groupKey) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n })\n setChoices(newChoices)\n }\n return\n }\n\n // Search input (when searchable) - handle first to capture alphanumeric keys\n if (config.searchable) {\n if (isBackspaceKey(key)) {\n setSearchQuery(searchRef.current.slice(0, -1))\n setCursorIndex(0)\n return\n }\n\n if (key.name === 'escape') {\n setSearchQuery('')\n setCursorIndex(findFirstSelectableIndex(choicesRef.current))\n return\n }\n\n // Alphanumeric input (except when Ctrl/Shift is held for shortcuts, or Tab)\n if (\n key.sequence &&\n !key.ctrl &&\n !key.shift &&\n !isTabKey(key) &&\n /^[a-zA-Z0-9\\-_./\\s]$/.test(key.sequence)\n ) {\n setSearchQuery(searchRef.current + key.sequence)\n setCursorIndex(0)\n return\n }\n }\n\n // Global toggle all: Ctrl+A (or 'a' when not searchable) - operates on filtered/visible choices only\n if ((key.name === 'a' && key.ctrl) || (key.name === 'a' && !key.shift && !config.searchable)) {\n const visibleChoices = filteredChoicesRef.current.filter(\n (c): c is NormalizedChoice<Value> => !Separator.isSeparator(c) && !c.disabled,\n )\n const allVisibleChecked = visibleChoices.every((c) => c.checked)\n const visibleValues = new Set(visibleChoices.map((c) => c.value))\n setChoices(\n choicesRef.current.map((choice) => {\n if (!choice.disabled && visibleValues.has(choice.value)) {\n return { ...choice, checked: !allVisibleChecked }\n }\n return choice\n }),\n )\n return\n }\n\n // Global invert: Ctrl+I (or 'i' when not searchable) - operates on filtered/visible choices only\n if ((key.name === 'i' && key.ctrl) || (key.name === 'i' && !key.shift && !config.searchable)) {\n const visibleChoices = filteredChoicesRef.current.filter(\n (c): c is NormalizedChoice<Value> => !Separator.isSeparator(c) && !c.disabled,\n )\n const visibleValues = new Set(visibleChoices.map((c) => c.value))\n setChoices(\n choicesRef.current.map((choice) => {\n if (!choice.disabled && visibleValues.has(choice.value)) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n }),\n )\n return\n }\n\n // Per-group toggle: 'A' (Shift+A) - operates on filtered/visible choices only\n if (key.name === 'a' && key.shift && currentGroupRef.current) {\n const group = currentGroupRef.current\n // Get visible choices in this group (filtered by search)\n const visibleGroupChoices = filteredChoicesRef.current.filter(\n (c): c is NormalizedChoice<Value> =>\n !Separator.isSeparator(c) && c.groupKey === group.key && !c.disabled,\n )\n const allVisibleChecked = visibleGroupChoices.every((c) => c.checked)\n const visibleValues = new Set(visibleGroupChoices.map((c) => c.value))\n // Toggle only the visible choices\n setChoices(\n choicesRef.current.map((choice) => {\n if (choice.groupKey === group.key && !choice.disabled && visibleValues.has(choice.value)) {\n return { ...choice, checked: !allVisibleChecked }\n }\n return choice\n }),\n )\n return\n }\n\n // Per-group invert: 'I' (Shift+I) - operates on filtered/visible choices only\n if (key.name === 'i' && key.shift && currentGroupRef.current) {\n const group = currentGroupRef.current\n // Get visible choices in this group (filtered by search)\n const visibleGroupChoices = filteredChoicesRef.current.filter(\n (c): c is NormalizedChoice<Value> =>\n !Separator.isSeparator(c) && c.groupKey === group.key && !c.disabled,\n )\n const visibleValues = new Set(visibleGroupChoices.map((c) => c.value))\n // Invert only the visible choices\n setChoices(\n choicesRef.current.map((choice) => {\n if (choice.groupKey === group.key && !choice.disabled && visibleValues.has(choice.value)) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n }),\n )\n return\n }\n\n // Tab: jump to next group\n if (isTabKey(key) && !key.shift) {\n if (currentGroupRef.current && filteredGroups.length > 1) {\n const currentGroupIdx = filteredGroups.findIndex((g) => g.key === currentGroupRef.current!.key)\n const nextGroupIdx = (currentGroupIdx + 1) % filteredGroups.length\n const nextGroup = filteredGroups[nextGroupIdx]\n if (nextGroup) {\n setCursorIndex(nextGroup.startIndex)\n }\n }\n return\n }\n\n // Shift+Tab: jump to previous group\n if (isTabKey(key) && key.shift) {\n if (currentGroupRef.current && filteredGroups.length > 1) {\n const currentGroupIdx = filteredGroups.findIndex((g) => g.key === currentGroupRef.current!.key)\n const prevGroupIdx = currentGroupIdx === 0 ? filteredGroups.length - 1 : currentGroupIdx - 1\n const prevGroup = filteredGroups[prevGroupIdx]\n if (prevGroup) {\n setCursorIndex(prevGroup.startIndex)\n }\n }\n return\n }\n })\n\n const page = usePagination<Item<Value>>({\n items: filteredChoices,\n active: cursorIndex,\n pageSize: config.pageSize ?? 15,\n renderItem: ({ item, index, isActive }) => {\n if (Separator.isSeparator(item)) {\n return ` ${item.separator}`\n }\n\n // Check if this is the first item in a group (render header)\n const group = filteredGroups.find((g) => g.startIndex === index)\n let header = ''\n if (group) {\n const stats = getGroupStats(group)\n const statsText = styleText('dim', ` (${stats.selected}/${stats.total})`)\n header = `\\n${theme.style.groupHeader(group.label, group.icon)}${statsText}\\n`\n }\n\n const checkbox = item.checked ? theme.icon.checked : theme.icon.unchecked\n const cursor = isActive ? theme.icon.cursor : ' '\n const color = item.checked ? theme.style.highlight : (text: string) => text\n const name = item.disabled\n ? theme.style.disabledChoice(\n `${item.name}${typeof item.disabled === 'string' ? ` (${item.disabled})` : ''}`,\n )\n : color(item.name)\n\n let line = `${header}${cursor} ${checkbox} ${name}`\n\n if (item.description && isActive) {\n line += `\\n ${theme.style.description(item.description)}`\n }\n\n return line\n },\n })\n\n // Build final output\n let message = config.message\n\n if (status === 'done') {\n const selections = buildSelections(choices, initialGroups)\n const totalSelected = Object.values(selections).reduce((sum, arr) => sum + arr.length, 0)\n message += styleText('cyan', ` ${totalSelected} item${totalSelected !== 1 ? 's' : ''} selected`)\n return `${prefix} ${message}`\n }\n\n let output = `${prefix} ${message}`\n\n if (config.searchable && searchQuery) {\n output += ` ${theme.style.searchQuery(`[${searchQuery}]`)}`\n }\n\n if (filteredChoices.length === 0) {\n output += `\\n${styleText('dim', ' No matches found')}`\n } else {\n output += `\\n${page}`\n }\n\n // Help text\n if (theme.helpMode === 'always' || (theme.helpMode === 'auto' && status === 'idle')) {\n const toggleKey = config.searchable ? 'ctrl+a' : 'a'\n const invertKey = config.searchable ? 'ctrl+i' : 'i'\n const helpText = [\n 'space: select',\n `${toggleKey}: toggle all`,\n `${invertKey}: invert`,\n config.searchable ? 'type to search' : '',\n ]\n .filter(Boolean)\n .join(', ')\n output += `\\n${styleText('dim', `(${helpText})`)}`\n }\n\n if (errorMessage) {\n output += `\\n${styleText('red', errorMessage)}`\n }\n\n return output\n },\n)\n\nexport default groupedCheckbox\nexport type { GroupedCheckboxTheme } from './theme.js'\nexport type {\n Choice,\n Group,\n GroupedCheckboxConfig,\n GroupedSelections,\n NormalizedChoice,\n NormalizedGroup,\n} from './types.js'\nexport { Separator }\n","import figures from '@inquirer/figures'\nimport { styleText } from 'node:util'\n\nexport interface GroupedCheckboxTheme {\n icon: {\n checked: string\n unchecked: string\n cursor: string\n }\n style: {\n disabledChoice: (text: string) => string\n groupHeader: (text: string, icon?: string) => string\n searchQuery: (text: string) => string\n highlight: (text: string) => string\n description: (text: string) => string\n }\n helpMode: 'always' | 'never' | 'auto'\n}\n\nexport const defaultTheme: GroupedCheckboxTheme = {\n icon: {\n checked: figures.circleFilled,\n unchecked: figures.circle,\n cursor: figures.pointer,\n },\n style: {\n disabledChoice: (text: string) => styleText('dim', text),\n groupHeader: (text: string, icon?: string) => styleText('bold', icon ? `${icon} ${text}` : text),\n searchQuery: (text: string) => styleText('cyan', text),\n highlight: (text: string) => styleText('cyan', text),\n description: (text: string) => styleText('dim', text),\n },\n helpMode: 'auto',\n}\n","import type { Theme } from '@inquirer/core'\nimport type { Prettify } from '@inquirer/type'\nimport type { GroupedCheckboxTheme } from './theme.js'\n\nexport interface Choice<Value> {\n value: Value\n name?: string\n description?: string\n short?: string\n disabled?: boolean | string\n checked?: boolean\n}\n\nexport interface Group<Value> {\n key: string\n label: string\n icon?: string\n choices: ReadonlyArray<Choice<Value>>\n}\n\nexport interface GroupedCheckboxConfig<Value> {\n message: string\n groups: ReadonlyArray<Group<Value>>\n searchable?: boolean\n pageSize?: number\n required?: boolean\n validate?: (selections: GroupedSelections<Value>) => boolean | string | Promise<boolean | string>\n theme?: PartialTheme\n}\n\nexport type PartialTheme = Prettify<Partial<Theme<GroupedCheckboxTheme>> & { checkbox?: Partial<GroupedCheckboxTheme> }>\n\nexport interface GroupedSelections<Value> {\n [groupKey: string]: Value[]\n}\n\nexport interface NormalizedChoice<Value> {\n value: Value\n name: string\n description?: string\n short: string\n disabled: boolean | string\n checked: boolean\n groupKey: string\n groupIndex: number\n indexInGroup: number\n}\n\nexport interface NormalizedGroup<Value> {\n key: string\n label: string\n icon?: string\n startIndex: number\n endIndex: number\n choices: NormalizedChoice<Value>[]\n}\n\nexport type Item<Value> = NormalizedChoice<Value> | Separator\n\nexport class Separator {\n readonly separator: string\n\n constructor(separator = '────────────────────') {\n this.separator = separator\n }\n\n static isSeparator(item: unknown): item is Separator {\n return item instanceof Separator\n }\n}\n","import type { Group, GroupedSelections, Item, NormalizedChoice, NormalizedGroup } from './types.js'\nimport { Separator } from './types.js'\n\nexport function normalizeGroups<Value>(groups: ReadonlyArray<Group<Value>>): {\n normalizedGroups: NormalizedGroup<Value>[]\n flatChoices: Item<Value>[]\n} {\n const normalizedGroups: NormalizedGroup<Value>[] = []\n const flatChoices: Item<Value>[] = []\n let flatIndex = 0\n\n groups.forEach((group, groupIndex) => {\n const startIndex = flatIndex\n const normalizedChoices: NormalizedChoice<Value>[] = []\n\n group.choices.forEach((choice, indexInGroup) => {\n const normalizedChoice: NormalizedChoice<Value> = {\n value: choice.value,\n name: choice.name ?? String(choice.value),\n description: choice.description,\n short: choice.short ?? choice.name ?? String(choice.value),\n disabled: choice.disabled ?? false,\n checked: choice.checked ?? false,\n groupKey: group.key,\n groupIndex,\n indexInGroup,\n }\n normalizedChoices.push(normalizedChoice)\n flatChoices.push(normalizedChoice)\n flatIndex++\n })\n\n normalizedGroups.push({\n key: group.key,\n label: group.label,\n icon: group.icon,\n startIndex,\n endIndex: flatIndex - 1,\n choices: normalizedChoices,\n })\n })\n\n return { normalizedGroups, flatChoices }\n}\n\nexport function filterBySearch<Value>(\n flatChoices: Item<Value>[],\n groups: NormalizedGroup<Value>[],\n query: string,\n): {\n filteredChoices: Item<Value>[]\n filteredGroups: NormalizedGroup<Value>[]\n} {\n if (!query) {\n return { filteredChoices: flatChoices, filteredGroups: groups }\n }\n\n const lowerQuery = query.toLowerCase()\n const filteredChoices: Item<Value>[] = []\n const filteredGroups: NormalizedGroup<Value>[] = []\n let flatIndex = 0\n\n for (const group of groups) {\n const matchingChoices: NormalizedChoice<Value>[] = []\n const startIndex = flatIndex\n\n // Use flatChoices (current state) filtered by groupKey, not group.choices (stale)\n const currentGroupChoices = flatChoices.filter(\n (c): c is NormalizedChoice<Value> => !Separator.isSeparator(c) && c.groupKey === group.key,\n )\n\n for (const choice of currentGroupChoices) {\n if (choice.name.toLowerCase().includes(lowerQuery)) {\n matchingChoices.push(choice)\n filteredChoices.push(choice)\n flatIndex++\n }\n }\n\n if (matchingChoices.length > 0) {\n filteredGroups.push({\n ...group,\n startIndex,\n endIndex: flatIndex - 1,\n choices: matchingChoices,\n })\n }\n }\n\n return { filteredChoices, filteredGroups }\n}\n\nexport function getCurrentGroup<Value>(\n cursorIndex: number,\n groups: NormalizedGroup<Value>[],\n): NormalizedGroup<Value> | undefined {\n return groups.find((group) => cursorIndex >= group.startIndex && cursorIndex <= group.endIndex)\n}\n\nexport function getSelectableInGroup<Value>(group: NormalizedGroup<Value>): NormalizedChoice<Value>[] {\n return group.choices.filter((choice) => !choice.disabled)\n}\n\nexport function toggleGroup<Value>(\n choices: NormalizedChoice<Value>[],\n group: NormalizedGroup<Value>,\n checked: boolean,\n): NormalizedChoice<Value>[] {\n return choices.map((choice) => {\n if (choice.groupKey === group.key && !choice.disabled) {\n return { ...choice, checked }\n }\n return choice\n })\n}\n\nexport function invertGroup<Value>(\n choices: NormalizedChoice<Value>[],\n group: NormalizedGroup<Value>,\n): NormalizedChoice<Value>[] {\n return choices.map((choice) => {\n if (choice.groupKey === group.key && !choice.disabled) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n })\n}\n\nexport function toggleAll<Value>(choices: NormalizedChoice<Value>[], checked: boolean): NormalizedChoice<Value>[] {\n return choices.map((choice) => {\n if (!choice.disabled) {\n return { ...choice, checked }\n }\n return choice\n })\n}\n\nexport function invertAll<Value>(choices: NormalizedChoice<Value>[]): NormalizedChoice<Value>[] {\n return choices.map((choice) => {\n if (!choice.disabled) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n })\n}\n\nexport function buildSelections<Value>(\n choices: NormalizedChoice<Value>[],\n groups: NormalizedGroup<Value>[],\n): GroupedSelections<Value> {\n const selections: GroupedSelections<Value> = {}\n\n for (const group of groups) {\n selections[group.key] = []\n }\n\n for (const choice of choices) {\n if (choice.checked) {\n const groupSelections = selections[choice.groupKey]\n if (groupSelections) {\n groupSelections.push(choice.value)\n }\n }\n }\n\n return selections\n}\n\nexport function isSelectableItem<Value>(item: Item<Value>): item is NormalizedChoice<Value> {\n return !Separator.isSeparator(item) && !item.disabled\n}\n\nexport function findNextSelectableIndex<Value>(items: Item<Value>[], currentIndex: number, direction: 1 | -1): number {\n const length = items.length\n if (length === 0) return -1\n\n let index = currentIndex + direction\n let iterations = 0\n\n while (iterations < length) {\n if (index < 0) index = length - 1\n if (index >= length) index = 0\n\n const item = items[index]\n if (item && isSelectableItem(item)) {\n return index\n }\n\n index += direction\n iterations++\n }\n\n return currentIndex\n}\n\nexport function findFirstSelectableIndex<Value>(items: Item<Value>[]): number {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n if (item && isSelectableItem(item)) {\n return i\n }\n }\n return 0\n}\n\nexport function getGroupStats<Value>(group: NormalizedGroup<Value>): { selected: number; total: number } {\n const selectable = getSelectableInGroup(group)\n const selected = selectable.filter((c) => c.checked).length\n return { selected, total: selectable.length }\n}\n"],"mappings":"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","names":["styleText","styleText"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/theme.ts","../src/types.ts","../src/utils.ts"],"sourcesContent":["import {\n createPrompt,\n isBackspaceKey,\n isDownKey,\n isEnterKey,\n isSpaceKey,\n isTabKey,\n isUpKey,\n makeTheme,\n useKeypress,\n useMemo,\n usePagination,\n usePrefix,\n useRef,\n useState,\n type KeypressEvent,\n type Status,\n} from '@inquirer/core'\nimport type { Context } from '@inquirer/type'\nimport { styleText } from 'node:util'\nimport { defaultTheme, type GroupedCheckboxTheme } from './theme.js'\nimport type { GroupedCheckboxConfig, GroupedSelections, Item, NormalizedChoice } from './types.js'\nimport { Separator } from './types.js'\nimport {\n buildSelections,\n filterBySearch,\n findFirstSelectableIndex,\n findNextSelectableIndex,\n getCurrentGroup,\n getGroupStats,\n isSelectableItem,\n normalizeGroups,\n} from './utils.js'\n\ninterface ExtendedKey extends KeypressEvent {\n shift: boolean\n sequence?: string\n}\n\nconst groupedCheckbox: <Value>(\n config: GroupedCheckboxConfig<Value>,\n context?: Context,\n) => Promise<GroupedSelections<Value>> = createPrompt(\n <Value>(config: GroupedCheckboxConfig<Value>, done: (value: GroupedSelections<Value>) => void) => {\n const { normalizedGroups: initialGroups, flatChoices: initialChoices } = useMemo(\n () => normalizeGroups(config.groups),\n [config.groups],\n )\n\n const [status, setStatus] = useState<Status>('idle')\n const [choices, setChoices] = useState<NormalizedChoice<Value>[]>(\n initialChoices.filter((item): item is NormalizedChoice<Value> => !Separator.isSeparator(item)),\n )\n const [searchQuery, setSearchQuery] = useState('')\n const [errorMessage, setErrorMessage] = useState<string | undefined>(undefined)\n const [cursorIndex, setCursorIndex] = useState(0)\n\n const theme = makeTheme<GroupedCheckboxTheme>(defaultTheme, config.theme?.checkbox)\n const prefix = usePrefix({ status, theme })\n\n const { filteredChoices, filteredGroups } = useMemo(\n () => filterBySearch(choices, initialGroups, searchQuery),\n [choices, initialGroups, searchQuery],\n )\n\n // Use ref to track current cursor for keypress handler\n const cursorRef = useRef(cursorIndex)\n cursorRef.current = cursorIndex\n\n const choicesRef = useRef(choices)\n choicesRef.current = choices\n\n const searchRef = useRef(searchQuery)\n searchRef.current = searchQuery\n\n const filteredChoicesRef = useRef(filteredChoices)\n filteredChoicesRef.current = filteredChoices\n\n const currentGroup = useMemo(() => getCurrentGroup(cursorIndex, filteredGroups), [cursorIndex, filteredGroups])\n\n const currentGroupRef = useRef(currentGroup)\n currentGroupRef.current = currentGroup\n\n useKeypress((event) => {\n const key = event as ExtendedKey\n if (status !== 'idle') return\n\n setErrorMessage(undefined)\n\n if (isEnterKey(key)) {\n const selections = buildSelections(choicesRef.current, initialGroups)\n\n if (config.required) {\n const hasSelection = Object.values(selections).some((arr) => arr.length > 0)\n if (!hasSelection) {\n setErrorMessage('At least one selection is required')\n return\n }\n }\n\n if (config.validate) {\n const result = config.validate(selections)\n if (result instanceof Promise) {\n setStatus('loading')\n result.then((validation) => {\n if (validation === true) {\n setStatus('done')\n done(selections)\n } else {\n setStatus('idle')\n setErrorMessage(typeof validation === 'string' ? validation : 'Invalid selection')\n }\n })\n return\n }\n if (result !== true) {\n setErrorMessage(typeof result === 'string' ? result : 'Invalid selection')\n return\n }\n }\n\n setStatus('done')\n done(selections)\n return\n }\n\n if (isUpKey(key)) {\n const newIndex = findNextSelectableIndex(filteredChoices, cursorRef.current, -1)\n setCursorIndex(newIndex)\n return\n }\n\n if (isDownKey(key)) {\n const newIndex = findNextSelectableIndex(filteredChoices, cursorRef.current, 1)\n setCursorIndex(newIndex)\n return\n }\n\n if (isSpaceKey(key)) {\n const currentItem = filteredChoices[cursorRef.current]\n if (currentItem && isSelectableItem(currentItem)) {\n const newChoices = choicesRef.current.map((choice) => {\n if (choice.value === currentItem.value && choice.groupKey === currentItem.groupKey) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n })\n setChoices(newChoices)\n }\n return\n }\n\n // Search input (when searchable) - handle first to capture alphanumeric keys\n if (config.searchable) {\n if (isBackspaceKey(key)) {\n setSearchQuery(searchRef.current.slice(0, -1))\n setCursorIndex(0)\n return\n }\n\n if (key.name === 'escape') {\n setSearchQuery('')\n setCursorIndex(findFirstSelectableIndex(choicesRef.current))\n return\n }\n\n // Alphanumeric input (except when Ctrl/Shift is held for shortcuts, or Tab)\n if (\n key.sequence &&\n !key.ctrl &&\n !key.shift &&\n !isTabKey(key) &&\n /^[a-zA-Z0-9\\-_./\\s]$/.test(key.sequence)\n ) {\n setSearchQuery(searchRef.current + key.sequence)\n setCursorIndex(0)\n return\n }\n }\n\n // Global toggle all: Ctrl+A (or 'a' when not searchable) - operates on filtered/visible choices only\n if ((key.name === 'a' && key.ctrl) || (key.name === 'a' && !key.shift && !config.searchable)) {\n const visibleChoices = filteredChoicesRef.current.filter(\n (c): c is NormalizedChoice<Value> => !Separator.isSeparator(c) && !c.disabled,\n )\n const allVisibleChecked = visibleChoices.every((c) => c.checked)\n const visibleValues = new Set(visibleChoices.map((c) => c.value))\n setChoices(\n choicesRef.current.map((choice) => {\n if (!choice.disabled && visibleValues.has(choice.value)) {\n return { ...choice, checked: !allVisibleChecked }\n }\n return choice\n }),\n )\n return\n }\n\n // Global invert: Ctrl+I (or 'i' when not searchable) - operates on filtered/visible choices only\n if ((key.name === 'i' && key.ctrl) || (key.name === 'i' && !key.shift && !config.searchable)) {\n const visibleChoices = filteredChoicesRef.current.filter(\n (c): c is NormalizedChoice<Value> => !Separator.isSeparator(c) && !c.disabled,\n )\n const visibleValues = new Set(visibleChoices.map((c) => c.value))\n setChoices(\n choicesRef.current.map((choice) => {\n if (!choice.disabled && visibleValues.has(choice.value)) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n }),\n )\n return\n }\n\n // Per-group toggle: 'A' (Shift+A) - operates on filtered/visible choices only\n if (key.name === 'a' && key.shift && currentGroupRef.current) {\n const group = currentGroupRef.current\n // Get visible choices in this group (filtered by search)\n const visibleGroupChoices = filteredChoicesRef.current.filter(\n (c): c is NormalizedChoice<Value> =>\n !Separator.isSeparator(c) && c.groupKey === group.key && !c.disabled,\n )\n const allVisibleChecked = visibleGroupChoices.every((c) => c.checked)\n const visibleValues = new Set(visibleGroupChoices.map((c) => c.value))\n // Toggle only the visible choices\n setChoices(\n choicesRef.current.map((choice) => {\n if (choice.groupKey === group.key && !choice.disabled && visibleValues.has(choice.value)) {\n return { ...choice, checked: !allVisibleChecked }\n }\n return choice\n }),\n )\n return\n }\n\n // Per-group invert: 'I' (Shift+I) - operates on filtered/visible choices only\n if (key.name === 'i' && key.shift && currentGroupRef.current) {\n const group = currentGroupRef.current\n // Get visible choices in this group (filtered by search)\n const visibleGroupChoices = filteredChoicesRef.current.filter(\n (c): c is NormalizedChoice<Value> =>\n !Separator.isSeparator(c) && c.groupKey === group.key && !c.disabled,\n )\n const visibleValues = new Set(visibleGroupChoices.map((c) => c.value))\n // Invert only the visible choices\n setChoices(\n choicesRef.current.map((choice) => {\n if (choice.groupKey === group.key && !choice.disabled && visibleValues.has(choice.value)) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n }),\n )\n return\n }\n\n // Tab: jump to next group\n if (isTabKey(key) && !key.shift) {\n if (currentGroupRef.current && filteredGroups.length > 1) {\n const currentGroupIdx = filteredGroups.findIndex((g) => g.key === currentGroupRef.current!.key)\n const nextGroupIdx = (currentGroupIdx + 1) % filteredGroups.length\n const nextGroup = filteredGroups[nextGroupIdx]\n if (nextGroup) {\n setCursorIndex(nextGroup.startIndex)\n }\n }\n return\n }\n\n // Shift+Tab: jump to previous group\n if (isTabKey(key) && key.shift) {\n if (currentGroupRef.current && filteredGroups.length > 1) {\n const currentGroupIdx = filteredGroups.findIndex((g) => g.key === currentGroupRef.current!.key)\n const prevGroupIdx = currentGroupIdx === 0 ? filteredGroups.length - 1 : currentGroupIdx - 1\n const prevGroup = filteredGroups[prevGroupIdx]\n if (prevGroup) {\n setCursorIndex(prevGroup.startIndex)\n }\n }\n return\n }\n })\n\n const page = usePagination<Item<Value>>({\n items: filteredChoices,\n active: cursorIndex,\n pageSize: config.pageSize ?? 15,\n renderItem: ({ item, index, isActive }) => {\n if (Separator.isSeparator(item)) {\n return ` ${item.separator}`\n }\n\n // Check if this is the first item in a group (render header)\n const group = filteredGroups.find((g) => g.startIndex === index)\n let header = ''\n if (group) {\n const stats = getGroupStats(group)\n const statsText = styleText('dim', ` (${stats.selected}/${stats.total})`)\n header = `\\n${theme.style.groupHeader(group.label, group.icon)}${statsText}\\n`\n }\n\n const checkbox = item.checked ? theme.icon.checked : theme.icon.unchecked\n const cursor = isActive ? theme.icon.cursor : ' '\n const color = item.checked ? theme.style.highlight : (text: string) => text\n const name = item.disabled\n ? theme.style.disabledChoice(\n `${item.name}${typeof item.disabled === 'string' ? ` (${item.disabled})` : ''}`,\n )\n : color(item.name)\n\n let line = `${header}${cursor} ${checkbox} ${name}`\n\n if (item.description && isActive) {\n line += `\\n ${theme.style.description(item.description)}`\n }\n\n return line\n },\n })\n\n // Build final output\n let message = config.message\n\n if (status === 'done') {\n const selections = buildSelections(choices, initialGroups)\n const totalSelected = Object.values(selections).reduce((sum, arr) => sum + arr.length, 0)\n message += styleText('cyan', ` ${totalSelected} item${totalSelected !== 1 ? 's' : ''} selected`)\n return `${prefix} ${message}`\n }\n\n let output = `${prefix} ${message}`\n\n if (config.searchable && searchQuery) {\n output += ` ${theme.style.searchQuery(`[${searchQuery}]`)}`\n }\n\n if (filteredChoices.length === 0) {\n output += `\\n${styleText('dim', ' No matches found')}`\n } else {\n output += `\\n${page}`\n }\n\n // Help text\n if (theme.helpMode === 'always' || (theme.helpMode === 'auto' && status === 'idle')) {\n const toggleKey = config.searchable ? 'ctrl+a' : 'a'\n const invertKey = config.searchable ? 'ctrl+i' : 'i'\n const helpText = [\n 'space: select',\n `${toggleKey}: toggle all`,\n `${invertKey}: invert`,\n config.searchable ? 'type to search' : '',\n ]\n .filter(Boolean)\n .join(', ')\n output += `\\n${styleText('dim', `(${helpText})`)}`\n }\n\n if (errorMessage) {\n output += `\\n${styleText('red', errorMessage)}`\n }\n\n return output\n },\n)\n\nexport default groupedCheckbox\nexport type { GroupedCheckboxTheme } from './theme.js'\nexport type {\n Choice,\n Group,\n GroupedCheckboxConfig,\n GroupedSelections,\n NormalizedChoice,\n NormalizedGroup,\n} from './types.js'\nexport { Separator }\n","import figures from '@inquirer/figures'\nimport { styleText } from 'node:util'\n\nexport interface GroupedCheckboxTheme {\n icon: {\n checked: string\n unchecked: string\n cursor: string\n }\n style: {\n disabledChoice: (text: string) => string\n groupHeader: (text: string, icon?: string) => string\n searchQuery: (text: string) => string\n highlight: (text: string) => string\n description: (text: string) => string\n }\n helpMode: 'always' | 'never' | 'auto'\n}\n\nexport const defaultTheme: GroupedCheckboxTheme = {\n icon: {\n checked: figures.circleFilled,\n unchecked: figures.circle,\n cursor: figures.pointer,\n },\n style: {\n disabledChoice: (text: string) => styleText('dim', text),\n groupHeader: (text: string, icon?: string) => styleText('bold', icon ? `${icon} ${text}` : text),\n searchQuery: (text: string) => styleText('cyan', text),\n highlight: (text: string) => styleText('cyan', text),\n description: (text: string) => styleText('dim', text),\n },\n helpMode: 'auto',\n}\n","import type { Theme } from '@inquirer/core'\nimport type { Prettify } from '@inquirer/type'\nimport type { GroupedCheckboxTheme } from './theme.js'\n\nexport interface Choice<Value> {\n value: Value\n name?: string\n description?: string\n short?: string\n disabled?: boolean | string\n checked?: boolean\n}\n\nexport interface Group<Value> {\n key: string\n label: string\n icon?: string\n choices: ReadonlyArray<Choice<Value>>\n}\n\nexport interface GroupedCheckboxConfig<Value> {\n message: string\n groups: ReadonlyArray<Group<Value>>\n searchable?: boolean\n pageSize?: number\n required?: boolean\n validate?: (selections: GroupedSelections<Value>) => boolean | string | Promise<boolean | string>\n theme?: PartialTheme\n}\n\nexport type PartialTheme = Prettify<Partial<Theme<GroupedCheckboxTheme>> & { checkbox?: Partial<GroupedCheckboxTheme> }>\n\nexport interface GroupedSelections<Value> {\n [groupKey: string]: Value[]\n}\n\nexport interface NormalizedChoice<Value> {\n value: Value\n name: string\n description?: string\n short: string\n disabled: boolean | string\n checked: boolean\n groupKey: string\n groupIndex: number\n indexInGroup: number\n}\n\nexport interface NormalizedGroup<Value> {\n key: string\n label: string\n icon?: string\n startIndex: number\n endIndex: number\n choices: NormalizedChoice<Value>[]\n}\n\nexport type Item<Value> = NormalizedChoice<Value> | Separator\n\nexport class Separator {\n readonly separator: string\n\n constructor(separator = '────────────────────') {\n this.separator = separator\n }\n\n static isSeparator(item: unknown): item is Separator {\n return item instanceof Separator\n }\n}\n","import type { Group, GroupedSelections, Item, NormalizedChoice, NormalizedGroup } from './types.js'\nimport { Separator } from './types.js'\n\nexport function normalizeGroups<Value>(groups: ReadonlyArray<Group<Value>>): {\n normalizedGroups: NormalizedGroup<Value>[]\n flatChoices: Item<Value>[]\n} {\n const normalizedGroups: NormalizedGroup<Value>[] = []\n const flatChoices: Item<Value>[] = []\n let flatIndex = 0\n\n groups.forEach((group, groupIndex) => {\n const startIndex = flatIndex\n const normalizedChoices: NormalizedChoice<Value>[] = []\n\n group.choices.forEach((choice, indexInGroup) => {\n const normalizedChoice: NormalizedChoice<Value> = {\n value: choice.value,\n name: choice.name ?? String(choice.value),\n description: choice.description,\n short: choice.short ?? choice.name ?? String(choice.value),\n disabled: choice.disabled ?? false,\n checked: choice.checked ?? false,\n groupKey: group.key,\n groupIndex,\n indexInGroup,\n }\n normalizedChoices.push(normalizedChoice)\n flatChoices.push(normalizedChoice)\n flatIndex++\n })\n\n normalizedGroups.push({\n key: group.key,\n label: group.label,\n icon: group.icon,\n startIndex,\n endIndex: flatIndex - 1,\n choices: normalizedChoices,\n })\n })\n\n return { normalizedGroups, flatChoices }\n}\n\nexport function filterBySearch<Value>(\n flatChoices: Item<Value>[],\n groups: NormalizedGroup<Value>[],\n query: string,\n): {\n filteredChoices: Item<Value>[]\n filteredGroups: NormalizedGroup<Value>[]\n} {\n if (!query) {\n return { filteredChoices: flatChoices, filteredGroups: groups }\n }\n\n const lowerQuery = query.toLowerCase()\n const filteredChoices: Item<Value>[] = []\n const filteredGroups: NormalizedGroup<Value>[] = []\n let flatIndex = 0\n\n for (const group of groups) {\n const matchingChoices: NormalizedChoice<Value>[] = []\n const startIndex = flatIndex\n\n // Use flatChoices (current state) filtered by groupKey, not group.choices (stale)\n const currentGroupChoices = flatChoices.filter(\n (c): c is NormalizedChoice<Value> => !Separator.isSeparator(c) && c.groupKey === group.key,\n )\n\n for (const choice of currentGroupChoices) {\n if (choice.name.toLowerCase().includes(lowerQuery)) {\n matchingChoices.push(choice)\n filteredChoices.push(choice)\n flatIndex++\n }\n }\n\n if (matchingChoices.length > 0) {\n filteredGroups.push({\n ...group,\n startIndex,\n endIndex: flatIndex - 1,\n choices: matchingChoices,\n })\n }\n }\n\n return { filteredChoices, filteredGroups }\n}\n\nexport function getCurrentGroup<Value>(\n cursorIndex: number,\n groups: NormalizedGroup<Value>[],\n): NormalizedGroup<Value> | undefined {\n return groups.find((group) => cursorIndex >= group.startIndex && cursorIndex <= group.endIndex)\n}\n\nexport function getSelectableInGroup<Value>(group: NormalizedGroup<Value>): NormalizedChoice<Value>[] {\n return group.choices.filter((choice) => !choice.disabled)\n}\n\nexport function toggleGroup<Value>(\n choices: NormalizedChoice<Value>[],\n group: NormalizedGroup<Value>,\n checked: boolean,\n): NormalizedChoice<Value>[] {\n return choices.map((choice) => {\n if (choice.groupKey === group.key && !choice.disabled) {\n return { ...choice, checked }\n }\n return choice\n })\n}\n\nexport function invertGroup<Value>(\n choices: NormalizedChoice<Value>[],\n group: NormalizedGroup<Value>,\n): NormalizedChoice<Value>[] {\n return choices.map((choice) => {\n if (choice.groupKey === group.key && !choice.disabled) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n })\n}\n\nexport function toggleAll<Value>(choices: NormalizedChoice<Value>[], checked: boolean): NormalizedChoice<Value>[] {\n return choices.map((choice) => {\n if (!choice.disabled) {\n return { ...choice, checked }\n }\n return choice\n })\n}\n\nexport function invertAll<Value>(choices: NormalizedChoice<Value>[]): NormalizedChoice<Value>[] {\n return choices.map((choice) => {\n if (!choice.disabled) {\n return { ...choice, checked: !choice.checked }\n }\n return choice\n })\n}\n\nexport function buildSelections<Value>(\n choices: NormalizedChoice<Value>[],\n groups: NormalizedGroup<Value>[],\n): GroupedSelections<Value> {\n const selections: GroupedSelections<Value> = {}\n\n for (const group of groups) {\n selections[group.key] = []\n }\n\n for (const choice of choices) {\n if (choice.checked) {\n const groupSelections = selections[choice.groupKey]\n if (groupSelections) {\n groupSelections.push(choice.value)\n }\n }\n }\n\n return selections\n}\n\nexport function isSelectableItem<Value>(item: Item<Value>): item is NormalizedChoice<Value> {\n return !Separator.isSeparator(item) && !item.disabled\n}\n\nexport function findNextSelectableIndex<Value>(items: Item<Value>[], currentIndex: number, direction: 1 | -1): number {\n const length = items.length\n if (length === 0) return -1\n\n let index = currentIndex + direction\n let iterations = 0\n\n while (iterations < length) {\n if (index < 0) index = length - 1\n if (index >= length) index = 0\n\n const item = items[index]\n if (item && isSelectableItem(item)) {\n return index\n }\n\n index += direction\n iterations++\n }\n\n return currentIndex\n}\n\nexport function findFirstSelectableIndex<Value>(items: Item<Value>[]): number {\n for (let i = 0; i < items.length; i++) {\n const item = items[i]\n if (item && isSelectableItem(item)) {\n return i\n }\n }\n return 0\n}\n\nexport function getGroupStats<Value>(group: NormalizedGroup<Value>): { selected: number; total: number } {\n const selectable = getSelectableInGroup(group)\n const selected = selectable.filter((c) => c.checked).length\n return { selected, total: selectable.length }\n}\n"],"mappings":"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","names":["styleText","styleText"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inquirer-grouped-checkbox",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "A searchable, grouped checkbox prompt for Inquirer.js",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -50,16 +50,16 @@
50
50
  "license": "MIT",
51
51
  "packageManager": "pnpm@10.24.0",
52
52
  "peerDependencies": {
53
- "@inquirer/core": ">=10.0.0"
53
+ "@inquirer/core": "^11.1.0"
54
54
  },
55
55
  "dependencies": {
56
- "@inquirer/figures": "^1.0.0"
56
+ "@inquirer/figures": "^2.0.2"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@arethetypeswrong/cli": "^0.18.2",
60
60
  "@eslint/js": "^9.39.2",
61
- "@inquirer/testing": "^2.0.0",
62
- "@inquirer/type": "^3.0.0",
61
+ "@inquirer/testing": "^3.0.3",
62
+ "@inquirer/type": "^4.0.2",
63
63
  "@types/node": "^25.0.3",
64
64
  "@vitest/ui": "^4.0.16",
65
65
  "eslint": "^9.39.2",