inquirerjs-checkbox-search 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Texarkanine
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,289 @@
1
+ # inquirerjs-checkbox-search
2
+
3
+ A multi-select prompt with text filtering/search capability for [inquirer.js](https://github.com/SBoudrias/Inquirer.js).
4
+
5
+ This prompt combines the functionality of `@inquirer/checkbox` and `@inquirer/search`, allowing you to:
6
+
7
+ - ✅ **Multi-select** multiple options with checkboxes
8
+ - 🔍 **Search/filter** options in real-time as you type
9
+ - ⌨️ **Navigate** with arrow keys through filtered results
10
+
11
+ ## Installation
12
+
13
+ <table>
14
+ <tr>
15
+ <th>npm</th>
16
+ <th>yarn</th>
17
+ <th>pnpm</th>
18
+ </tr>
19
+ <tr>
20
+ <td>
21
+
22
+ ```sh
23
+ npm install inquirerjs-checkbox-search
24
+ ```
25
+
26
+ </td>
27
+ <td>
28
+
29
+ ```sh
30
+ yarn add inquirerjs-checkbox-search
31
+ ```
32
+
33
+ </td>
34
+ <td>
35
+
36
+ ```sh
37
+ pnpm add inquirerjs-checkbox-search
38
+ ```
39
+
40
+ </td>
41
+ </tr>
42
+ </table>
43
+
44
+ ## Usage
45
+
46
+ ### Quick Start
47
+
48
+ ```typescript
49
+ import checkboxSearch from 'inquirerjs-checkbox-search';
50
+
51
+ const selected = await checkboxSearch({
52
+ message: 'Which frameworks do you use?',
53
+ choices: [
54
+ { value: 'react', name: 'React' },
55
+ { value: 'vue', name: 'Vue.js' },
56
+ { value: 'angular', name: 'Angular' },
57
+ ],
58
+ });
59
+
60
+ console.log('Selected:', selected);
61
+ // => ['react', 'vue']
62
+ ```
63
+
64
+ ## API
65
+
66
+ ### Options
67
+
68
+ | Property | Type | Required | Description |
69
+ | -------------- | ----------------------------------------------------------------------------------- | -------- | ------------------------------------------------------ |
70
+ | `message` | `string` | Yes | The question to ask |
71
+ | `choices` | `Array<Choice \| string \| Separator>` | No\* | Static list of choices |
72
+ | `source` | `(term?: string, opt: { signal: AbortSignal }) => Promise<Array<Choice \| string>>` | No\* | Async function for dynamic choices |
73
+ | `pageSize` | `number` | No | Number of choices to display per page (default: 7) |
74
+ | `loop` | `boolean` | No | Whether to loop around when navigating (default: true) |
75
+ | `required` | `boolean` | No | Require at least one selection (default: false) |
76
+ | `validate` | `(selection: Array<Choice>) => boolean \| string \| Promise<string \| boolean>` | No | Custom validation function |
77
+ | `instructions` | `string \| boolean` | No | Custom instructions text or false to hide |
78
+ | `theme` | `Theme` | No | Custom theme configuration |
79
+ | `default` | `Array<Value>` | No | Initially selected values |
80
+ | `filter` | `(items: Array<Choice>, term: string) => Array<Choice>` | No | Custom filter function |
81
+
82
+ \*Either `choices` or `source` must be provided.
83
+
84
+ ### Choice Object
85
+
86
+ ```typescript
87
+ type Choice<Value = any> = {
88
+ value: Value; // The value returned when selected
89
+ name?: string; // Display text (defaults to value)
90
+ description?: string; // Additional description shown below
91
+ short?: string; // Shorter text for final answer
92
+ disabled?: boolean | string; // Whether choice is selectable
93
+ checked?: boolean; // Initially selected
94
+ };
95
+ ```
96
+
97
+ ### Theme Options
98
+
99
+ ```typescript
100
+ type CheckboxSearchTheme = {
101
+ icon: {
102
+ checked: string | ((text: string) => string);
103
+ unchecked: string | ((text: string) => string);
104
+ cursor: string | ((text: string) => string);
105
+ };
106
+ style: {
107
+ answer: (text: string) => string;
108
+ message: (text: string) => string;
109
+ error: (text: string) => string;
110
+ help: (text: string) => string;
111
+ highlight: (text: string) => string;
112
+ searchTerm: (text: string) => string;
113
+ description: (text: string) => string;
114
+ disabled: (text: string) => string;
115
+ };
116
+ helpMode: 'always' | 'never' | 'auto';
117
+ };
118
+ ```
119
+
120
+ ## Keyboard Controls
121
+
122
+ | Key | Action |
123
+ | ------------------------- | ---------------------------------- |
124
+ | <kbd>Type</kbd> | Filter/search options |
125
+ | <kbd>↑</kbd>/<kbd>↓</kbd> | Navigate through options |
126
+ | <kbd>Tab</kbd> | Toggle selection of current option |
127
+ | <kbd>Escape</kbd> | Clear search filter |
128
+ | <kbd>Enter</kbd> | Confirm selection |
129
+
130
+ ## Advanced Features
131
+
132
+ For detailed examples of advanced features, see the [`examples/`](./examples/) directory:
133
+
134
+ - **[Basic Multi-Select](./examples/basic.js)** - Simple multi-select functionality
135
+ - **[Search Filtering](./examples/search-filtering.js)** - Real-time search with larger lists
136
+ - **[Async Source](./examples/async-source.js)** - Dynamic loading with mock API
137
+ - **[Custom Theme](./examples/custom-theme.js)** - Custom icons and styling
138
+ - **[Validation](./examples/validation.js)** - Input validation and pre-selection
139
+ - **[Custom Filter](./examples/custom-filter.js)** - Fuzzy matching filter
140
+
141
+ **To run examples:**
142
+
143
+ 1. Build the package: `npm run build`
144
+ 2. Run any example: `node examples/basic.js`
145
+
146
+ See the [examples README](./examples/README.md) for detailed instructions.
147
+
148
+ Each example includes detailed comments and demonstrates real-world usage patterns.
149
+
150
+ ## Developer Guide
151
+
152
+ This section covers the tools and workflows used in this project for contributors and maintainers.
153
+
154
+ ### Tools Overview
155
+
156
+ #### Build System
157
+
158
+ - **[tshy](https://github.com/isaacs/tshy)** - Modern TypeScript build tool that generates both ESM and CommonJS outputs
159
+ - Configuration in `package.json` under `tshy` field
160
+ - Builds to `dist/esm/` and `dist/commonjs/`
161
+ - Automatically handles dual exports
162
+
163
+ #### Package Management
164
+
165
+ - **npm** - Package manager (npm 9+ required)
166
+ - **Node.js 18+** - Runtime requirement
167
+ - **package.json** - Standard npm configuration with dual exports
168
+
169
+ #### Code Quality
170
+
171
+ - **[ESLint](https://eslint.org/)** - Linting with TypeScript support
172
+ - Configuration: `eslint.config.js`
173
+ - Rules: TypeScript ESLint recommended + Prettier integration
174
+ - **[Prettier](https://prettier.io/)** - Code formatting
175
+ - Configuration: `.prettierrc`
176
+ - **[TypeScript](https://www.typescriptlang.org/)** - Type checking and compilation
177
+ - Configuration: `tsconfig.json`, `tsconfig.test.json`
178
+
179
+ #### Testing
180
+
181
+ - **[Vitest](https://vitest.dev/)** - Fast testing framework
182
+ - Configuration: `vitest.config.ts`
183
+ - Features: TypeScript support, coverage, UI mode, watch mode
184
+ - **[@inquirer/testing](https://www.npmjs.com/package/@inquirer/testing)** - Testing utilities for inquirer prompts
185
+ - **[@vitest/coverage-v8](https://www.npmjs.com/package/@vitest/coverage-v8)** - Coverage reporting
186
+
187
+ #### Development Tools
188
+
189
+ - **[@arethetypeswrong/cli](https://github.com/arethetypeswrong/arethetypeswrong.github.io)** - Package validation for dual exports
190
+ - **[rimraf](https://github.com/isaacs/rimraf)** - Cross-platform file deletion
191
+
192
+ ### Development Workflows
193
+
194
+ #### Setup & Installation
195
+
196
+ ```bash
197
+ # Clone and install
198
+ git clone https://github.com/texarkanine/inquirerjs-checkbox-search.git
199
+ cd inquirerjs-checkbox-search
200
+ npm install
201
+ ```
202
+
203
+ #### Development Commands
204
+
205
+ ```bash
206
+ # Development (watch mode)
207
+ npm run dev # Build in watch mode with tshy
208
+
209
+ # Building
210
+ npm run build # Build for production
211
+ npm run clean # Clean build artifacts
212
+
213
+ # Code Quality
214
+ npm run lint # Run ESLint (with --fix)
215
+ npm run format # Format code with Prettier
216
+ npm run typecheck # TypeScript type checking
217
+
218
+ # Testing
219
+ npm test # Run all code quality checks + tests
220
+ npm run test:unit # Run unit tests only
221
+ npm run test:coverage # Run tests with coverage report
222
+ npm run test:ui # Run tests with Vitest UI
223
+ npm run test:unit -- --watch # Run tests in watch mode
224
+
225
+ # Package Validation
226
+ npm run attw # Validate package exports with arethetypeswrong
227
+
228
+ # Pre-publish
229
+ npm run prepublishOnly # Full build + test + validation pipeline
230
+ ```
231
+
232
+ #### File Structure
233
+
234
+ ```
235
+ ├── src/
236
+ │ ├── index.ts # Main prompt implementation
237
+ │ └── *.test.ts # Test files (excluded from build)
238
+ ├── dist/ # Built output (generated by tshy)
239
+ │ ├── esm/ # ES modules
240
+ │ └── commonjs/ # CommonJS
241
+ ├── .github/
242
+ │ └── workflows/ # CI/CD workflows
243
+ ├── node_modules/ # Dependencies
244
+ ├── package.json # Package config with tshy setup
245
+ ├── tsconfig.json # TypeScript config
246
+ ├── vitest.config.ts # Test config
247
+ ├── eslint.config.js # Linting config
248
+ └── .prettierrc # Formatting config
249
+ ```
250
+
251
+ #### Quality Assurance Workflow
252
+
253
+ 1. **Before Committing**
254
+
255
+ ```bash
256
+ npm test # Run all quality checks + tests
257
+ ```
258
+
259
+ 2. **Before Publishing**
260
+ ```bash
261
+ npm run prepublishOnly # Full validation pipeline
262
+ ```
263
+
264
+ #### Build & Release Workflow
265
+
266
+ 1. **Development Build**
267
+
268
+ ```bash
269
+ npm run build # One-time build
270
+ npm run dev # Watch mode for development
271
+ ```
272
+
273
+ 2. **Package Validation**
274
+
275
+ ```bash
276
+ npm run attw # Validate dual exports work correctly
277
+ ```
278
+
279
+ 3. **Release Process** (Automated)
280
+ - Push changes to `main` branch
281
+ - Release Please creates/updates release PR
282
+ - Merge release PR to trigger:
283
+ - GitHub release creation
284
+ - npm package publication
285
+ - Version tag creation
286
+
287
+ ## Contributing
288
+
289
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and contribution guidelines.
@@ -0,0 +1,82 @@
1
+ import { Separator, type Theme } from '@inquirer/core';
2
+ import type { PartialDeep } from '@inquirer/type';
3
+ /**
4
+ * Theme configuration for the checkbox-search prompt
5
+ */
6
+ type CheckboxSearchTheme = {
7
+ icon: {
8
+ checked: string | ((text: string) => string);
9
+ unchecked: string | ((text: string) => string);
10
+ cursor: string | ((text: string) => string);
11
+ };
12
+ style: {
13
+ answer: (text: string) => string;
14
+ message: (text: string) => string;
15
+ error: (text: string) => string;
16
+ help: (text: string) => string;
17
+ highlight: (text: string) => string;
18
+ searchTerm: (text: string) => string;
19
+ description: (text: string) => string;
20
+ disabled: (text: string) => string;
21
+ };
22
+ helpMode: 'always' | 'never' | 'auto';
23
+ };
24
+ /**
25
+ * Choice object for the checkbox-search prompt
26
+ */
27
+ export type Choice<Value> = {
28
+ value: Value;
29
+ name?: string;
30
+ description?: string;
31
+ short?: string;
32
+ disabled?: boolean | string;
33
+ checked?: boolean;
34
+ type?: never;
35
+ };
36
+ /**
37
+ * Normalized choice object used internally
38
+ */
39
+ export type NormalizedChoice<Value> = {
40
+ value: Value;
41
+ name: string;
42
+ description?: string;
43
+ short: string;
44
+ disabled: boolean | string;
45
+ checked: boolean;
46
+ };
47
+ /**
48
+ * Main checkbox-search prompt implementation
49
+ *
50
+ * A multi-select prompt with text filtering/search capability that combines
51
+ * the functionality of checkbox and search prompts from inquirer.js.
52
+ *
53
+ * Features:
54
+ * - Real-time search/filtering of options
55
+ * - Multi-selection with checkboxes
56
+ * - Keyboard navigation and shortcuts
57
+ * - Support for both static and async data sources
58
+ * - Customizable themes and validation
59
+ *
60
+ * @param config - Configuration options for the prompt
61
+ * @param done - Callback function called when prompt completes
62
+ */
63
+ declare const _default: <Value>(config: {
64
+ message: string;
65
+ prefix?: string | undefined;
66
+ pageSize?: number | undefined;
67
+ instructions?: string | boolean | undefined;
68
+ choices?: readonly (string | Separator)[] | readonly (Separator | Choice<Value>)[] | undefined;
69
+ source?: ((term: string | undefined, opt: {
70
+ signal: AbortSignal;
71
+ }) => readonly (string | Separator)[] | readonly (Separator | Choice<Value>)[] | Promise<readonly (string | Separator)[]> | Promise<readonly (Separator | Choice<Value>)[]>) | undefined;
72
+ filter?: ((items: readonly NormalizedChoice<Value>[], term: string) => readonly NormalizedChoice<Value>[]) | undefined;
73
+ loop?: boolean | undefined;
74
+ required?: boolean | undefined;
75
+ validate?: ((choices: readonly NormalizedChoice<Value>[]) => boolean | string | Promise<string | boolean>) | undefined;
76
+ theme?: PartialDeep<Theme<CheckboxSearchTheme>> | undefined;
77
+ default?: readonly Value[] | undefined;
78
+ }, context?: import("@inquirer/type").Context) => Promise<Value[]> & {
79
+ cancel: () => void;
80
+ };
81
+ export default _default;
82
+ export { Separator } from '@inquirer/core';