From 83d31868940af4bafda472cfae3315e47a32c888 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 30 Aug 2026 21:49:33 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Add=20pagination?= =?UTF-8?q?=20indicator=20and=20tab-completion=20hint=20to=20command=20sug?= =?UTF-8?q?gestions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .Jules/palette.md | 3 +++ src/cli/ui/components/CommandInput.tsx | 15 +++++++++++++-- src/cli/ui/components/CommandSuggestionList.tsx | 11 ++++++++++- 3 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 .Jules/palette.md diff --git a/.Jules/palette.md b/.Jules/palette.md new file mode 100644 index 00000000..af4cdb74 --- /dev/null +++ b/.Jules/palette.md @@ -0,0 +1,3 @@ +## 2026-08-30 - Visual Pagination and Tab-Completion Hints in Terminal UIs +**Learning:** Terminal UI lists with `maxVisible` limits that truncate suggestions (like `CommandSuggestionList`) can cause users to lose situational awareness of how many total items exist, and hidden tab-completion shortcuts can be unintuitive for users expecting standard terminal behavior. Adding pagination indicators (e.g., `1-5 of 12`) and explicit shortcut hints (`⇥ complete`) dramatically improves discoverability and clarity without cluttering the interface. +**Action:** When designing or updating truncated lists in terminal UIs (like ink), always include a visual indicator of the total item count and explicit hints for available keyboard shortcuts (like tab completion) in the status bar to preserve context and discoverability. \ No newline at end of file diff --git a/src/cli/ui/components/CommandInput.tsx b/src/cli/ui/components/CommandInput.tsx index 3f05f99b..cdeba23c 100644 --- a/src/cli/ui/components/CommandInput.tsx +++ b/src/cli/ui/components/CommandInput.tsx @@ -261,7 +261,12 @@ export const CommandInput: React.FC = ({ {isIntercepting && ( - + {isSelecting ? pendingSelection?.title @@ -296,7 +301,11 @@ export const CommandInput: React.FC = ({ {isSelected ? '❯ ' : ' '} {isMultiSelecting && ( - + {selectedItems.includes(item.id) ? '[x] ' : '[ ] '} )} @@ -315,6 +324,8 @@ export const CommandInput: React.FC = ({ suggestions={visibleSuggestions} selectedIndex={selectedIndex - startIndex} parentCommand={activeCommand} + totalSuggestions={suggestions.length} + startIndex={startIndex} /> )} diff --git a/src/cli/ui/components/CommandSuggestionList.tsx b/src/cli/ui/components/CommandSuggestionList.tsx index 7e66838a..dd1986b0 100644 --- a/src/cli/ui/components/CommandSuggestionList.tsx +++ b/src/cli/ui/components/CommandSuggestionList.tsx @@ -9,12 +9,16 @@ interface CommandSuggestionListProps { selectedIndex: number; parentCommand?: Command; filterText?: string; + totalSuggestions?: number; + startIndex?: number; } export const CommandSuggestionList: React.FC = ({ suggestions, selectedIndex, parentCommand, + totalSuggestions = 0, + startIndex = 0, }) => { if (suggestions.length === 0) return null; @@ -116,7 +120,12 @@ export const CommandSuggestionList: React.FC = ({ - ↑↓ nav · ⏎ select · esc close + {totalSuggestions > suggestions.length && ( + + {startIndex + 1}-{startIndex + suggestions.length} of {totalSuggestions} ·{' '} + + )} + ↑↓ nav · ⇥ complete · ⏎ select · esc close From d317efe9e594d3bba29b8f7ff824fbec8085d47f Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 31 Aug 2026 16:13:50 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=8E=A8=20Palette:=20Fix=20PR=20feedba?= =?UTF-8?q?ck,=20address=20formatting=20noise,=20make=20props=20mandatory,?= =?UTF-8?q?=20and=20fix=20journal=20case?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .Jules/palette.md | 3 -- .jules/palette.md | 4 ++ src/cli/ui/components/CommandInput.tsx | 13 +---- .../ui/components/CommandSuggestionList.tsx | 8 +-- .../command-suggestion-list.test.tsx | 54 +++++++++++++++++++ 5 files changed, 64 insertions(+), 18 deletions(-) delete mode 100644 .Jules/palette.md create mode 100644 tests/unit/cli/ui/components/command-suggestion-list.test.tsx diff --git a/.Jules/palette.md b/.Jules/palette.md deleted file mode 100644 index af4cdb74..00000000 --- a/.Jules/palette.md +++ /dev/null @@ -1,3 +0,0 @@ -## 2026-08-30 - Visual Pagination and Tab-Completion Hints in Terminal UIs -**Learning:** Terminal UI lists with `maxVisible` limits that truncate suggestions (like `CommandSuggestionList`) can cause users to lose situational awareness of how many total items exist, and hidden tab-completion shortcuts can be unintuitive for users expecting standard terminal behavior. Adding pagination indicators (e.g., `1-5 of 12`) and explicit shortcut hints (`⇥ complete`) dramatically improves discoverability and clarity without cluttering the interface. -**Action:** When designing or updating truncated lists in terminal UIs (like ink), always include a visual indicator of the total item count and explicit hints for available keyboard shortcuts (like tab completion) in the status bar to preserve context and discoverability. \ No newline at end of file diff --git a/.jules/palette.md b/.jules/palette.md index 559dc665..2d8b72ff 100644 --- a/.jules/palette.md +++ b/.jules/palette.md @@ -1,3 +1,7 @@ ## 2026-08-29 - Truncation Awareness **Learning:** When displaying dynamic lists in terminal UIs (such as those using `ink`), if the list is truncated to fit constraints (e.g., a `maxVisible` limit), it is important to include an explicit visual indicator to preserve user situational awareness. **Action:** Always add an explicit UI element indicating truncation and count, rather than silently hiding items. + +## 2026-08-31 - Visual Pagination and Tab-Completion Hints in Terminal UIs +**Learning:** Terminal UI lists with `maxVisible` limits that truncate suggestions (like `CommandSuggestionList`) can cause users to lose situational awareness of how many total items exist, and hidden tab-completion shortcuts can be unintuitive for users expecting standard terminal behavior. Adding pagination indicators (e.g., `1-5 of 12`) and explicit shortcut hints (`⇥ complete`) dramatically improves discoverability and clarity without cluttering the interface. +**Action:** When designing or updating truncated lists in terminal UIs (like ink), always include a visual indicator of the total item count and explicit hints for available keyboard shortcuts (like tab completion) in the status bar to preserve context and discoverability. diff --git a/src/cli/ui/components/CommandInput.tsx b/src/cli/ui/components/CommandInput.tsx index cdeba23c..47afbf1b 100644 --- a/src/cli/ui/components/CommandInput.tsx +++ b/src/cli/ui/components/CommandInput.tsx @@ -261,12 +261,7 @@ export const CommandInput: React.FC = ({ {isIntercepting && ( - + {isSelecting ? pendingSelection?.title @@ -301,11 +296,7 @@ export const CommandInput: React.FC = ({ {isSelected ? '❯ ' : ' '} {isMultiSelecting && ( - + {selectedItems.includes(item.id) ? '[x] ' : '[ ] '} )} diff --git a/src/cli/ui/components/CommandSuggestionList.tsx b/src/cli/ui/components/CommandSuggestionList.tsx index dd1986b0..8157a723 100644 --- a/src/cli/ui/components/CommandSuggestionList.tsx +++ b/src/cli/ui/components/CommandSuggestionList.tsx @@ -9,16 +9,16 @@ interface CommandSuggestionListProps { selectedIndex: number; parentCommand?: Command; filterText?: string; - totalSuggestions?: number; - startIndex?: number; + totalSuggestions: number; + startIndex: number; } export const CommandSuggestionList: React.FC = ({ suggestions, selectedIndex, parentCommand, - totalSuggestions = 0, - startIndex = 0, + totalSuggestions, + startIndex, }) => { if (suggestions.length === 0) return null; diff --git a/tests/unit/cli/ui/components/command-suggestion-list.test.tsx b/tests/unit/cli/ui/components/command-suggestion-list.test.tsx new file mode 100644 index 00000000..1988f65e --- /dev/null +++ b/tests/unit/cli/ui/components/command-suggestion-list.test.tsx @@ -0,0 +1,54 @@ +import { render } from '@testing-library/react'; +import React from 'react'; + +mock.module('ink', () => ({ + Box: (props: any) => React.createElement('div', null, props.children), + Text: (props: any) => React.createElement('span', null, props.children), +})); + +describe('CommandSuggestionList pagination', () => { + async function loadCommandSuggestionList() { + return (await import('../../../../../src/cli/ui/components/CommandSuggestionList.js')) + .CommandSuggestionList; + } + + it('hides pagination indicator when totalSuggestions <= suggestions.length', async () => { + const CommandSuggestionList = await loadCommandSuggestionList(); + + const { container } = render( + , + ); + + // It should contain the shortcuts but NOT the pagination numbers + expect(container.textContent).toContain('↑↓ nav · ⇥ complete · ⏎ select · esc close'); + expect(container.textContent).not.toContain('1-2 of 2'); + }); + + it('shows pagination indicator when totalSuggestions > suggestions.length', async () => { + const CommandSuggestionList = await loadCommandSuggestionList(); + + const { container } = render( + , + ); + + // It should contain both the pagination numbers (3-4 of 12) and the shortcuts + expect(container.textContent).toContain('3-4 of 12'); + expect(container.textContent).toContain('↑↓ nav · ⇥ complete · ⏎ select · esc close'); + }); +});