inquirerjs-checkbox-search 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -32
- package/dist/commonjs/index.d.ts +2 -1
- package/dist/commonjs/index.js +19 -16
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.js +19 -16
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -90,7 +90,7 @@ type PageSizeConfig = {
|
|
|
90
90
|
1. Start with base page size (from `base` or auto-calculated)
|
|
91
91
|
2. Calculate buffer:
|
|
92
92
|
- If `autoBufferDescriptions` is true: Add lines needed for largest description
|
|
93
|
-
-
|
|
93
|
+
- Add `buffer` value (if specified)
|
|
94
94
|
- Ensure buffer is at least `minBuffer` (if specified)
|
|
95
95
|
3. Subtract buffer from base page size
|
|
96
96
|
4. Apply `min`/`max` constraints
|
|
@@ -101,21 +101,22 @@ type PageSizeConfig = {
|
|
|
101
101
|
```typescript
|
|
102
102
|
type CheckboxSearchTheme = {
|
|
103
103
|
icon: {
|
|
104
|
-
checked: string | ((text: string) => string);
|
|
105
|
-
unchecked: string | ((text: string) => string);
|
|
106
|
-
cursor: string | ((text: string) => string);
|
|
104
|
+
checked: string | ((text: string) => string); // Icon for checked items
|
|
105
|
+
unchecked: string | ((text: string) => string); // Icon for unchecked items
|
|
106
|
+
cursor: string | ((text: string) => string); // Icon for cursor/current item
|
|
107
|
+
nocursor?: string; // Icon/space placeholder for cursor
|
|
107
108
|
};
|
|
108
109
|
style: {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
110
|
+
message: (text: string) => string; // Style for prompt message
|
|
111
|
+
error: (text: string) => string; // Style for error messages
|
|
112
|
+
help: (text: string) => string; // Style for help text
|
|
113
|
+
highlight: (text: string) => string; // Style for highlighted items (takes precedence)
|
|
114
|
+
searchTerm: (text: string) => string; // Style for search term display
|
|
115
|
+
description: (text: string) => string; // Style for item descriptions
|
|
116
|
+
disabled: (text: string) => string; // Style for disabled items
|
|
117
|
+
checked: (text: string) => string; // Style for checked items
|
|
117
118
|
};
|
|
118
|
-
helpMode: 'always' | 'never' | 'auto';
|
|
119
|
+
helpMode: 'always' | 'never' | 'auto'; // When to show help text
|
|
119
120
|
};
|
|
120
121
|
```
|
|
121
122
|
|
|
@@ -220,20 +221,17 @@ npm run prepublishOnly # Full build + test + validation pipeline
|
|
|
220
221
|
#### File Structure
|
|
221
222
|
|
|
222
223
|
```
|
|
223
|
-
├── src/
|
|
224
|
-
│ ├── index.ts
|
|
225
|
-
│ └──
|
|
226
|
-
├── dist/
|
|
227
|
-
│ ├── esm/
|
|
228
|
-
│ └── commonjs/
|
|
229
|
-
├──
|
|
230
|
-
|
|
231
|
-
├──
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
├── vitest.config.ts # Test config
|
|
235
|
-
├── eslint.config.js # Linting config
|
|
236
|
-
└── .prettierrc # Formatting config
|
|
224
|
+
├── src/ # actual source code
|
|
225
|
+
│ ├── index.ts
|
|
226
|
+
│ └── __tests__/
|
|
227
|
+
├── dist/ # build output
|
|
228
|
+
│ ├── esm/
|
|
229
|
+
│ └── commonjs/
|
|
230
|
+
├── examples/ # usage examples
|
|
231
|
+
├── demos/ # scripts to record GIFs from examples
|
|
232
|
+
├── docs/ # documentation resources
|
|
233
|
+
│ └── img/
|
|
234
|
+
└── scripts/ # build and utility scripts
|
|
237
235
|
```
|
|
238
236
|
|
|
239
237
|
#### Demo Generation
|
|
@@ -247,12 +245,12 @@ To generate demos locally, run `npm run demo:generate:all` (requires `docker`).
|
|
|
247
245
|
1. **Before Committing**
|
|
248
246
|
|
|
249
247
|
```bash
|
|
250
|
-
npm test
|
|
248
|
+
npm test
|
|
251
249
|
```
|
|
252
250
|
|
|
253
251
|
2. **Before Publishing**
|
|
254
252
|
```bash
|
|
255
|
-
npm run prepublishOnly
|
|
253
|
+
npm run prepublishOnly
|
|
256
254
|
```
|
|
257
255
|
|
|
258
256
|
#### Build & Release Workflow
|
|
@@ -260,19 +258,20 @@ To generate demos locally, run `npm run demo:generate:all` (requires `docker`).
|
|
|
260
258
|
1. **Development Build**
|
|
261
259
|
|
|
262
260
|
```bash
|
|
263
|
-
npm run build
|
|
264
|
-
npm run dev
|
|
261
|
+
npm run build
|
|
262
|
+
npm run dev
|
|
265
263
|
```
|
|
266
264
|
|
|
267
265
|
2. **Package Validation**
|
|
268
266
|
|
|
269
267
|
```bash
|
|
270
|
-
npm run attw
|
|
268
|
+
npm run attw
|
|
271
269
|
```
|
|
272
270
|
|
|
273
271
|
3. **Release Process** (Automated)
|
|
274
272
|
- Push changes to `main` branch
|
|
275
273
|
- Release Please creates/updates release PR
|
|
274
|
+
- demo images are generated and added to the PR
|
|
276
275
|
- Merge release PR to trigger:
|
|
277
276
|
- GitHub release creation
|
|
278
277
|
- npm package publication
|
package/dist/commonjs/index.d.ts
CHANGED
|
@@ -8,9 +8,9 @@ type CheckboxSearchTheme = {
|
|
|
8
8
|
checked: string | ((text: string) => string);
|
|
9
9
|
unchecked: string | ((text: string) => string);
|
|
10
10
|
cursor: string | ((text: string) => string);
|
|
11
|
+
nocursor?: string | ((text: string) => string);
|
|
11
12
|
};
|
|
12
13
|
style: {
|
|
13
|
-
answer: (text: string) => string;
|
|
14
14
|
message: (text: string) => string;
|
|
15
15
|
error: (text: string) => string;
|
|
16
16
|
help: (text: string) => string;
|
|
@@ -18,6 +18,7 @@ type CheckboxSearchTheme = {
|
|
|
18
18
|
searchTerm: (text: string) => string;
|
|
19
19
|
description: (text: string) => string;
|
|
20
20
|
disabled: (text: string) => string;
|
|
21
|
+
checked: (text: string) => string;
|
|
21
22
|
};
|
|
22
23
|
helpMode: 'always' | 'never' | 'auto';
|
|
23
24
|
};
|
package/dist/commonjs/index.js
CHANGED
|
@@ -20,9 +20,9 @@ const checkboxSearchTheme = {
|
|
|
20
20
|
checked: yoctocolors_cjs_1.default.green(figures_1.default.circleFilled),
|
|
21
21
|
unchecked: figures_1.default.circle,
|
|
22
22
|
cursor: figures_1.default.pointer,
|
|
23
|
+
nocursor: ' ', // Default: single space when cursor is not active
|
|
23
24
|
},
|
|
24
25
|
style: {
|
|
25
|
-
answer: yoctocolors_cjs_1.default.cyan,
|
|
26
26
|
message: yoctocolors_cjs_1.default.cyan,
|
|
27
27
|
error: (text) => yoctocolors_cjs_1.default.yellow(`> ${text}`),
|
|
28
28
|
help: yoctocolors_cjs_1.default.dim,
|
|
@@ -30,6 +30,7 @@ const checkboxSearchTheme = {
|
|
|
30
30
|
searchTerm: yoctocolors_cjs_1.default.cyan,
|
|
31
31
|
description: yoctocolors_cjs_1.default.cyan,
|
|
32
32
|
disabled: yoctocolors_cjs_1.default.dim,
|
|
33
|
+
checked: yoctocolors_cjs_1.default.green,
|
|
33
34
|
},
|
|
34
35
|
helpMode: 'always',
|
|
35
36
|
};
|
|
@@ -190,10 +191,8 @@ function resolvePageSize(pageSize, items) {
|
|
|
190
191
|
if (pageSize.autoBufferDescriptions) {
|
|
191
192
|
buffer += calculateDescriptionLines(items, pageSize.autoBufferCountsLineWidth || false);
|
|
192
193
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
buffer += pageSize.buffer || 0;
|
|
196
|
-
}
|
|
194
|
+
// 2c: Add buffer value (always if specified)
|
|
195
|
+
buffer += pageSize.buffer || 0;
|
|
197
196
|
// 2d: Ensure at least minBuffer
|
|
198
197
|
if (pageSize.minBuffer !== undefined) {
|
|
199
198
|
buffer = Math.max(buffer, pageSize.minBuffer);
|
|
@@ -537,26 +536,27 @@ exports.default = (0, core_1.createPrompt)((config, done) => {
|
|
|
537
536
|
}
|
|
538
537
|
return undefined;
|
|
539
538
|
}, [active, filteredItems]);
|
|
540
|
-
//
|
|
539
|
+
// Helper function to resolve icon (string or function)
|
|
540
|
+
const resolveIcon = (icon, choiceText) => {
|
|
541
|
+
return typeof icon === 'function' ? icon(choiceText) : icon;
|
|
542
|
+
};
|
|
543
|
+
// Create renderItem function that's reactive to current state but minimizes recreations
|
|
541
544
|
const renderItem = (0, core_1.useMemo)(() => {
|
|
542
545
|
return ({ item, isActive }) => {
|
|
543
546
|
const line = [];
|
|
544
547
|
if (core_1.Separator.isSeparator(item)) {
|
|
545
548
|
return yoctocolors_cjs_1.default.dim(item.separator);
|
|
546
549
|
}
|
|
547
|
-
//
|
|
548
|
-
const
|
|
549
|
-
|
|
550
|
-
const isChecked = currentItem?.checked || false;
|
|
551
|
-
// Helper function to resolve icon (string or function)
|
|
552
|
-
const resolveIcon = (icon, choiceText) => {
|
|
553
|
-
return typeof icon === 'function' ? icon(choiceText) : icon;
|
|
554
|
-
};
|
|
550
|
+
// Direct access to the checked state (item is from the same source as allItems)
|
|
551
|
+
const isChecked = !core_1.Separator.isSeparator(item) &&
|
|
552
|
+
item.checked;
|
|
555
553
|
const choiceName = item.name;
|
|
556
554
|
const checkbox = resolveIcon(isChecked ? theme.icon.checked : theme.icon.unchecked, choiceName);
|
|
555
|
+
// If active, use the cursor icon, otherwise use appropriate spacing to align items
|
|
557
556
|
const cursor = isActive
|
|
558
557
|
? resolveIcon(theme.icon.cursor, choiceName)
|
|
559
|
-
: ' ';
|
|
558
|
+
: resolveIcon(theme.icon.nocursor ?? ' ', choiceName);
|
|
559
|
+
// Keep cursor and checkbox as separate elements so join(' ') adds the proper space between them
|
|
560
560
|
line.push(cursor, checkbox);
|
|
561
561
|
let text = item.name;
|
|
562
562
|
if (isActive) {
|
|
@@ -566,6 +566,9 @@ exports.default = (0, core_1.createPrompt)((config, done) => {
|
|
|
566
566
|
else if (item.disabled) {
|
|
567
567
|
text = theme.style.disabled(text);
|
|
568
568
|
}
|
|
569
|
+
else if (isChecked) {
|
|
570
|
+
text = theme.style.checked(text);
|
|
571
|
+
}
|
|
569
572
|
line.push(text);
|
|
570
573
|
// Show disabled reason if item is disabled (but no descriptions inline anymore)
|
|
571
574
|
if (item.disabled) {
|
|
@@ -577,7 +580,7 @@ exports.default = (0, core_1.createPrompt)((config, done) => {
|
|
|
577
580
|
// NOTE: Removed the inline description display - descriptions now appear at bottom
|
|
578
581
|
return line.join(' ');
|
|
579
582
|
};
|
|
580
|
-
}, [
|
|
583
|
+
}, [theme, config.theme]);
|
|
581
584
|
// Setup pagination
|
|
582
585
|
const page = (0, core_1.usePagination)({
|
|
583
586
|
items: filteredItems,
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -8,9 +8,9 @@ type CheckboxSearchTheme = {
|
|
|
8
8
|
checked: string | ((text: string) => string);
|
|
9
9
|
unchecked: string | ((text: string) => string);
|
|
10
10
|
cursor: string | ((text: string) => string);
|
|
11
|
+
nocursor?: string | ((text: string) => string);
|
|
11
12
|
};
|
|
12
13
|
style: {
|
|
13
|
-
answer: (text: string) => string;
|
|
14
14
|
message: (text: string) => string;
|
|
15
15
|
error: (text: string) => string;
|
|
16
16
|
help: (text: string) => string;
|
|
@@ -18,6 +18,7 @@ type CheckboxSearchTheme = {
|
|
|
18
18
|
searchTerm: (text: string) => string;
|
|
19
19
|
description: (text: string) => string;
|
|
20
20
|
disabled: (text: string) => string;
|
|
21
|
+
checked: (text: string) => string;
|
|
21
22
|
};
|
|
22
23
|
helpMode: 'always' | 'never' | 'auto';
|
|
23
24
|
};
|
package/dist/esm/index.js
CHANGED
|
@@ -10,9 +10,9 @@ const checkboxSearchTheme = {
|
|
|
10
10
|
checked: colors.green(figures.circleFilled),
|
|
11
11
|
unchecked: figures.circle,
|
|
12
12
|
cursor: figures.pointer,
|
|
13
|
+
nocursor: ' ', // Default: single space when cursor is not active
|
|
13
14
|
},
|
|
14
15
|
style: {
|
|
15
|
-
answer: colors.cyan,
|
|
16
16
|
message: colors.cyan,
|
|
17
17
|
error: (text) => colors.yellow(`> ${text}`),
|
|
18
18
|
help: colors.dim,
|
|
@@ -20,6 +20,7 @@ const checkboxSearchTheme = {
|
|
|
20
20
|
searchTerm: colors.cyan,
|
|
21
21
|
description: colors.cyan,
|
|
22
22
|
disabled: colors.dim,
|
|
23
|
+
checked: colors.green,
|
|
23
24
|
},
|
|
24
25
|
helpMode: 'always',
|
|
25
26
|
};
|
|
@@ -180,10 +181,8 @@ export function resolvePageSize(pageSize, items) {
|
|
|
180
181
|
if (pageSize.autoBufferDescriptions) {
|
|
181
182
|
buffer += calculateDescriptionLines(items, pageSize.autoBufferCountsLineWidth || false);
|
|
182
183
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
buffer += pageSize.buffer || 0;
|
|
186
|
-
}
|
|
184
|
+
// 2c: Add buffer value (always if specified)
|
|
185
|
+
buffer += pageSize.buffer || 0;
|
|
187
186
|
// 2d: Ensure at least minBuffer
|
|
188
187
|
if (pageSize.minBuffer !== undefined) {
|
|
189
188
|
buffer = Math.max(buffer, pageSize.minBuffer);
|
|
@@ -527,26 +526,27 @@ export default createPrompt((config, done) => {
|
|
|
527
526
|
}
|
|
528
527
|
return undefined;
|
|
529
528
|
}, [active, filteredItems]);
|
|
530
|
-
//
|
|
529
|
+
// Helper function to resolve icon (string or function)
|
|
530
|
+
const resolveIcon = (icon, choiceText) => {
|
|
531
|
+
return typeof icon === 'function' ? icon(choiceText) : icon;
|
|
532
|
+
};
|
|
533
|
+
// Create renderItem function that's reactive to current state but minimizes recreations
|
|
531
534
|
const renderItem = useMemo(() => {
|
|
532
535
|
return ({ item, isActive }) => {
|
|
533
536
|
const line = [];
|
|
534
537
|
if (Separator.isSeparator(item)) {
|
|
535
538
|
return colors.dim(item.separator);
|
|
536
539
|
}
|
|
537
|
-
//
|
|
538
|
-
const
|
|
539
|
-
|
|
540
|
-
const isChecked = currentItem?.checked || false;
|
|
541
|
-
// Helper function to resolve icon (string or function)
|
|
542
|
-
const resolveIcon = (icon, choiceText) => {
|
|
543
|
-
return typeof icon === 'function' ? icon(choiceText) : icon;
|
|
544
|
-
};
|
|
540
|
+
// Direct access to the checked state (item is from the same source as allItems)
|
|
541
|
+
const isChecked = !Separator.isSeparator(item) &&
|
|
542
|
+
item.checked;
|
|
545
543
|
const choiceName = item.name;
|
|
546
544
|
const checkbox = resolveIcon(isChecked ? theme.icon.checked : theme.icon.unchecked, choiceName);
|
|
545
|
+
// If active, use the cursor icon, otherwise use appropriate spacing to align items
|
|
547
546
|
const cursor = isActive
|
|
548
547
|
? resolveIcon(theme.icon.cursor, choiceName)
|
|
549
|
-
: ' ';
|
|
548
|
+
: resolveIcon(theme.icon.nocursor ?? ' ', choiceName);
|
|
549
|
+
// Keep cursor and checkbox as separate elements so join(' ') adds the proper space between them
|
|
550
550
|
line.push(cursor, checkbox);
|
|
551
551
|
let text = item.name;
|
|
552
552
|
if (isActive) {
|
|
@@ -556,6 +556,9 @@ export default createPrompt((config, done) => {
|
|
|
556
556
|
else if (item.disabled) {
|
|
557
557
|
text = theme.style.disabled(text);
|
|
558
558
|
}
|
|
559
|
+
else if (isChecked) {
|
|
560
|
+
text = theme.style.checked(text);
|
|
561
|
+
}
|
|
559
562
|
line.push(text);
|
|
560
563
|
// Show disabled reason if item is disabled (but no descriptions inline anymore)
|
|
561
564
|
if (item.disabled) {
|
|
@@ -567,7 +570,7 @@ export default createPrompt((config, done) => {
|
|
|
567
570
|
// NOTE: Removed the inline description display - descriptions now appear at bottom
|
|
568
571
|
return line.join(' ');
|
|
569
572
|
};
|
|
570
|
-
}, [
|
|
573
|
+
}, [theme, config.theme]);
|
|
571
574
|
// Setup pagination
|
|
572
575
|
const page = usePagination({
|
|
573
576
|
items: filteredItems,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "inquirerjs-checkbox-search",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "A multi-select prompt with text filtering for inquirer.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"answer",
|
|
@@ -86,6 +86,7 @@
|
|
|
86
86
|
"demo:generate": "node scripts/generate-demo.js",
|
|
87
87
|
"demo:generate:basic": "node scripts/generate-demo.js basic",
|
|
88
88
|
"demo:generate:validation": "node scripts/generate-demo.js validation",
|
|
89
|
+
"demo:generate:custom-theme": "node scripts/generate-demo.js custom-theme",
|
|
89
90
|
"demo:generate:all": "node scripts/generate-demo.js all"
|
|
90
91
|
},
|
|
91
92
|
"dependencies": {
|