From 5c28abfad90571c78f4230907b3e3b397284b349 Mon Sep 17 00:00:00 2001 From: Snaylaker Date: Thu, 6 Nov 2025 22:25:32 +0100 Subject: [PATCH] feat(cli): add keyboard shortcuts help to multiselect prompts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add note() before first multiselect to show keyboard shortcuts - Help text: Use ↑/↓ to navigate • Space to select/deselect • Enter to confirm - Show help only once to avoid cluttering the interface - Add unit test to verify note() is called with correct message Improves UX by helping users understand multiselect navigation --- packages/cta-cli/src/ui-prompts.ts | 10 ++++++++++ packages/cta-cli/tests/ui-prompts.test.ts | 8 +++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/cta-cli/src/ui-prompts.ts b/packages/cta-cli/src/ui-prompts.ts index 35d0305d..c0e6b1c3 100644 --- a/packages/cta-cli/src/ui-prompts.ts +++ b/packages/cta-cli/src/ui-prompts.ts @@ -3,6 +3,7 @@ import { confirm, isCancel, multiselect, + note, select, text, } from '@clack/prompts' @@ -103,6 +104,9 @@ export async function selectPackageManager(): Promise { return packageManager } +// Track if we've shown the multiselect help text +let hasShownMultiselectHelp = false + export async function selectAddOns( framework: Framework, mode: string, @@ -116,6 +120,12 @@ export async function selectAddOns( return [] } + // Show help text only once + if (!hasShownMultiselectHelp) { + note('Use ↑/↓ to navigate • Space to select/deselect • Enter to confirm', 'Keyboard Shortcuts') + hasShownMultiselectHelp = true + } + const value = await multiselect({ message, options: addOns diff --git a/packages/cta-cli/tests/ui-prompts.test.ts b/packages/cta-cli/tests/ui-prompts.test.ts index 987ca33f..9d039876 100644 --- a/packages/cta-cli/tests/ui-prompts.test.ts +++ b/packages/cta-cli/tests/ui-prompts.test.ts @@ -93,7 +93,8 @@ describe('selectPackageManager', () => { }) describe('selectAddOns', () => { - it('should select some add-ons', async () => { + it('should show keyboard shortcuts help and select add-ons', async () => { + const noteSpy = vi.spyOn(clack, 'note').mockImplementation(() => {}) vi.spyOn(clack, 'multiselect').mockImplementation(async () => ['add-on-1']) vi.spyOn(clack, 'isCancel').mockImplementation(() => false) @@ -114,7 +115,12 @@ describe('selectAddOns', () => { 'add-on', 'Select add-ons', ) + expect(packageManager).toEqual(['add-on-1']) + expect(noteSpy).toHaveBeenCalledWith( + 'Use ↑/↓ to navigate • Space to select/deselect • Enter to confirm', + 'Keyboard Shortcuts', + ) }) it('should exit on cancel', async () => {