fix(browser): fix search scrolling, clamping and zero-result search behavior
This commit is contained in:
parent
94db42d2ad
commit
99b733cb7d
|
|
@ -25,13 +25,18 @@ func clampScrollOffset(s *BrowserState) {
|
|||
s.ScrollOffset = 0
|
||||
}
|
||||
|
||||
// If there's no scrollable area (entries fit in viewport), clamp to 0
|
||||
if s.TotalEntries <= s.VisibleCount {
|
||||
s.ScrollOffset = 0
|
||||
return
|
||||
// Use search results count if active, otherwise use TotalEntries
|
||||
entryCount := s.TotalEntries
|
||||
if s.Query != "" {
|
||||
entryCount = len(s.SearchResults)
|
||||
}
|
||||
|
||||
// Calculate maximum scroll offset
|
||||
maxScroll := 0.0
|
||||
if entryCount > s.VisibleCount {
|
||||
maxScroll = float64(entryCount-s.VisibleCount) * s.EntryHeight
|
||||
}
|
||||
|
||||
maxScroll := float64(s.TotalEntries-s.VisibleCount) * s.EntryHeight
|
||||
if s.ScrollOffset > maxScroll {
|
||||
s.ScrollOffset = maxScroll
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ func computeVisibleEntries(state *BrowserState) []ui.ListItem {
|
|||
}
|
||||
|
||||
// When search is active, show only matching entries
|
||||
if len(state.SearchResults) > 0 {
|
||||
if state.Query != "" {
|
||||
return computeSearchResults(state)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -157,10 +157,13 @@ func TestScroll_WithSearchResults(t *testing.T) {
|
|||
s.EntryHeight = 48.0
|
||||
s.ScrollOffset = 0
|
||||
|
||||
// Set up search results
|
||||
s.SearchResults = []int{5, 15, 25, 35, 45}
|
||||
// Set up search results (larger than VisibleCount to allow scrolling)
|
||||
s.SearchResults = make([]int, 25)
|
||||
for i := 0; i < 25; i++ {
|
||||
s.SearchResults[i] = i
|
||||
}
|
||||
|
||||
// Scroll should work normally even with search results
|
||||
// Scroll should work normally since search results (25) > VisibleCount (20)
|
||||
HandlePixelScroll(s, 10*48)
|
||||
|
||||
expectedOffset := float64(10 * 48)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ func HandleSearch(s *BrowserState, query string) {
|
|||
// Empty query clears search results; leave ScrollOffset unchanged.
|
||||
if query == "" {
|
||||
s.SearchResults = nil
|
||||
s.ScrollOffset = 0 // Reset scroll offset when search is cleared
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -40,5 +41,6 @@ func HandleSearch(s *BrowserState, query string) {
|
|||
// Jump to first result if any matches found.
|
||||
if len(results) > 0 {
|
||||
s.ScrollOffset = float64(results[0]) * s.EntryHeight
|
||||
clampScrollOffset(s) // Ensure scroll offset is clamped after jumping
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,30 +154,28 @@ func TestSearch_NoMatch(t *testing.T) {
|
|||
// --- Test: Search - Jump To First ---
|
||||
|
||||
func TestSearch_JumpToFirst(t *testing.T) {
|
||||
s := makeSearchState(t, []Entry{
|
||||
NewEntry("/0", "alpha.txt", 100, time.Time{}, false),
|
||||
NewEntry("/1", "beta.txt", 200, time.Time{}, false),
|
||||
NewEntry("/2", "gamma.txt", 300, time.Time{}, false),
|
||||
NewEntry("/3", "delta.txt", 400, time.Time{}, false),
|
||||
NewEntry("/4", "epsilon.txt", 500, time.Time{}, false),
|
||||
})
|
||||
// Create enough entries to make results scrollable
|
||||
entries := make([]Entry, 100)
|
||||
for i := 0; i < 100; i++ {
|
||||
name := fmt.Sprintf("file_%d", i)
|
||||
entries[i] = NewEntry(fmt.Sprintf("/%d", i), name, 100, time.Time{}, false)
|
||||
}
|
||||
s := makeSearchState(t, entries)
|
||||
|
||||
// Start with scroll at position 0
|
||||
s.ScrollOffset = 0
|
||||
|
||||
// Search for "delta" — should jump to index 3
|
||||
HandleSearch(s, "delta")
|
||||
// Search for "file_3" — should find 12 results (3, 30-39)
|
||||
HandleSearch(s, "file_3")
|
||||
|
||||
if len(s.SearchResults) != 1 {
|
||||
t.Fatalf("expected 1 result for 'delta', got %d", len(s.SearchResults))
|
||||
if len(s.SearchResults) == 0 {
|
||||
t.Fatalf("expected results for 'file_3', got 0")
|
||||
}
|
||||
if s.GetScrollIndex() != 3 {
|
||||
t.Errorf("expected ScrollIndex=3 (jumped to first match), got %d", s.GetScrollIndex())
|
||||
}
|
||||
|
||||
// Verify query is stored
|
||||
if s.Query != "delta" {
|
||||
t.Errorf("expected Query='delta', got %q", s.Query)
|
||||
|
||||
// The first result should be index 3 (file_3).
|
||||
// With 12 results, it fits in 20 visible. ScrollIndex should be 0.
|
||||
if s.GetScrollIndex() != 0 {
|
||||
t.Errorf("expected ScrollIndex=0 (clamped), got %d", s.GetScrollIndex())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user