Skip to content

fix(ios): hide catalog item count labels and category filter behind search overlay#1897

Draft
Copilot wants to merge 3 commits intomainfrom
copilot/fix-catalog-search-overlay-issue-again
Draft

fix(ios): hide catalog item count labels and category filter behind search overlay#1897
Copilot wants to merge 3 commits intomainfrom
copilot/fix-catalog-search-overlay-issue-again

Conversation

Copy link
Contributor

Copilot AI commented Mar 9, 2026

On iOS, the FlatList's ListHeaderComponent ("Showing X of Y items") and CategoriesFilter remained rendered beneath the LargeTitleHeader search overlay, causing them to peek through at the top of the screen during active search.

Changes

  • CatalogItemsScreen.tsx
    • isSearching now derives from raw searchValue.trim().length > 0 instead of the debounced value, so CategoriesFilter and ListHeaderComponent hide/show immediately when the user starts or clears the search — no 400ms lag
    • Added isQueryReady = debouncedSearchValue.trim().length > 0 to gate when vector search results are ready to display
    • Gate CategoriesFilter render on !isSearching
    • Return null from ListHeaderComponent when isSearching is true
    • Show the loading spinner in the search overlay while !isQueryReady || isVectorLoading, covering the debounce window before the vector fetch fires
const isSearching = searchValue.trim().length > 0;
const isQueryReady = debouncedSearchValue.trim().length > 0;

// ...

{!isSearching && (
  <CategoriesFilter ... />
)}

// ...

ListHeaderComponent={
  !isSearching ? (
    <View className="mb-4">
      <Text>{totalItemsText}</Text>
      {paginatedItems.length > 0 && <Text>{showingText}</Text>}
    </View>
  ) : null
}

// In search overlay content:
{isSearching ? (
  !isQueryReady || isVectorLoading ? (
    <ActivityIndicator ... />  // shown during debounce + fetch
  ) : (
    // results
  )
) : ...}

Both elements are restored immediately when the user clears the search.

Original prompt

This section details on the original issue you should resolve

<issue_title>iOS – Catalog Search Overlay Shows "Showing X of Y Items" Label Peeking</issue_title>
<issue_description>Description:
On iOS, when using the Catalog search:

  • Tapping the search icon overlays the search results screen correctly.
  • However, the “Showing X of Y items” label peeks between the search bar and the results overlay, partially visible.

This creates a visual layering issue, making the UI appear broken or misaligned.

Steps to Reproduce:

  1. Open the app on iOS
  2. Navigate to the Catalog screen
  3. Tap the Search icon
  4. Observe the overlay and the “Showing X of Y items” label

Screenshots / Screen Recordings:

Image

Expected Result:
The search overlay should completely cover the Catalog items and associated labels; no underlying text should peek through.

Actual Result:
The “Showing X of Y items” label is partially visible between the search bar and the results overlay.

Environment:

  • Device: iPhone (13 Pro)

Additional Notes:

  • This is iOS-specific</issue_description>

Comments on the Issue (you are @copilot in this section)

@andrew-bierman @copilot Assigned for POC development. Please investigate and create a proof of concept implementation.

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Summary by CodeRabbit

  • Bug Fixes
    • Hidden category filters during active search to streamline the search experience.
    • Updated header display to conditionally render based on search state, removing unnecessary UI elements when searching.
    • Modified item count display to show only when browsing non-search results.

…alog search on iOS

Co-authored-by: andrew-bierman <94939237+andrew-bierman@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix catalog search overlay peeking label issue on iOS fix(ios): hide catalog item count labels and category filter behind search overlay Mar 9, 2026
@andrew-bierman
Copy link
Collaborator

@coderabbitai Please review this PR for code quality, best practices, and potential issues.

@coderabbitai
Copy link

coderabbitai bot commented Mar 9, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find the CatalogItemsScreen file
fd "CatalogItemsScreen" --type f

# Also check the git diff for this PR
git diff HEAD~1 HEAD --name-only

Length of output: 115


🏁 Script executed:

#!/bin/bash
cat apps/expo/features/catalog/screens/CatalogItemsScreen.tsx

Length of output: 9847


@andrew-bierman: The PR description image shows an iOS screenshot with "Showing 20 of 197,717 items" text peeking through a red-highlighted area just below the search bar overlay — the visual bug this PR is fixing.

The overall approach is correct and clean. Here's my review:


🐛 Critical – searchResults can be undefined at runtime

searchResults is derived as:

const searchResults = vectorResult?.items;

When vectorResult is undefined (e.g., before any result arrives, or on error), searchResults is undefined. It is then used without a null-guard:

{searchResults.length > 0 && ...}   // 💥 TypeError
{searchResults.map((item: CatalogItem) => ...)}  // 💥 TypeError

Fix:

const searchResults: CatalogItem[] = vectorResult?.items ?? [];

This also removes the need for the inline CatalogItem type annotation in .map().


⚠️ Medium – isSearching debounce delay partially re-introduces the peeking bug

isSearching is derived from the debounced value:

const isSearching = debouncedSearchValue.length > 0;

With a 400 ms debounce, the "Showing X of Y" label and CategoriesFilter remain visible for up to 400 ms after the user starts typing — the overlay appears, but the elements beneath it are still rendered, which can still produce the peeking effect during that window.

Fix: Use the raw searchValue to control the visibility guard, and keep debouncedSearchValue only for the actual API query:

const isSearching = searchValue.length > 0;         // instant hide/show
const isQueryReady = debouncedSearchValue.length > 0; // controls API call

Then gate useVectorSearch on isQueryReady (or pass debouncedSearchValue as-is, which you already do).


🔧 Minor – Unused destructured variable _isVectorFetching

isFetching: _isVectorFetching,

Since this value is never used, it can simply be removed from the destructuring to keep the code clean:

const {
  data: vectorResult,
  isLoading: isVectorLoading,
  error: vectorError,
} = useVectorSearch({ query: debouncedSearchValue, limit: 10 });

💡 Suggestion – key={activeFilter} on FlatList forces full remount

<FlatList key={activeFilter} ...>

Using key to remount the list on filter change is a quick workaround but causes the entire list (including scroll position, item caches, etc.) to be torn down and rebuilt. Consider using extraData={activeFilter} instead, and let the data prop change drive the re-render naturally. (Note: this is a pre-existing pattern, not introduced by this PR.)


✅ What's done well

  • Gating both CategoriesFilter and ListHeaderComponent on !isSearching is the correct minimal fix.
  • loadMore already correctly skips fetchNextPage when isSearching is true.
  • ItemSeparatorComponent is correctly memoized with useMemo.
  • Error and empty states are cleanly handled inline throughout.

@andrew-bierman
Copy link
Collaborator

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Mar 9, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link

coderabbitai bot commented Mar 9, 2026

Warning

Rate limit exceeded

@andrew-bierman has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 10 minutes and 2 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4bf1d3d1-3cea-4119-b332-3a903b242ae4

📥 Commits

Reviewing files that changed from the base of the PR and between 45df246 and c3e7a85.

📒 Files selected for processing (1)
  • apps/expo/features/catalog/screens/CatalogItemsScreen.tsx
📝 Walkthrough

Walkthrough

Modified CatalogItemsScreen.tsx to hide the categories filter and catalog header content when a search is active. This prevents UI elements from peeking through the search overlay by conditionally rendering components based on the isSearching state.

Changes

Cohort / File(s) Summary
Search State UI Refinement
apps/expo/features/catalog/screens/CatalogItemsScreen.tsx
Wrapped CategoriesFilter and ListHeaderComponent in conditional checks to hide them when search is active. Moved "Showing X of Y items" text render into the non-search conditional block.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

Poem

🐰 When search takes the stage, the clutter must fade,
Hide filters and labels—a cleaner parade!
No peeking allowed when the query's alight,
Just results in focus, pristine and bright! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: hiding catalog item count labels and category filter during search overlay on iOS, matching the primary objective.
Linked Issues check ✅ Passed The code changes (hiding CategoriesFilter and ListHeaderComponent during search) directly address the iOS visual layering issue described in #1849, where labels peeked through the search overlay.
Out of Scope Changes check ✅ Passed All changes in CatalogItemsScreen.tsx are scoped to hiding the header content and filter during search, directly addressing the linked issue without introducing unrelated modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch copilot/fix-catalog-search-overlay-issue-again

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/expo/features/catalog/screens/CatalogItemsScreen.tsx`:
- Around line 164-173: The UI gating currently uses isSearching derived from
debouncedSearchValue which causes a 400ms lag; change isSearching in
CatalogItemsScreen to derive from the raw searchValue (e.g.,
Boolean(searchValue?.trim())) so the CategoriesFilter and list header hide/show
immediately, while keeping debouncedSearchValue only for triggering the vector
query and data fetch; update any places that check isSearching (filter render
and header render) to use the new isSearching derived from searchValue and leave
debouncedSearchValue usage confined to the query logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 059688ca-45d6-4d2f-be4b-9abefdf29e89

📥 Commits

Reviewing files that changed from the base of the PR and between 3f94763 and 45df246.

📒 Files selected for processing (1)
  • apps/expo/features/catalog/screens/CatalogItemsScreen.tsx

@andrew-bierman
Copy link
Collaborator

@copilot Please address the CodeRabbit review feedback on this PR (1 inline comments).

@andrew-bierman
Copy link
Collaborator

@copilot CodeRabbit has reviewed this PR. Please address the feedback.

@andrew-bierman
Copy link
Collaborator

@copilot CodeRabbit has reviewed this PR. Please address the feedback.

… for query

Co-authored-by: andrew-bierman <94939237+andrew-bierman@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 9, 2026

@copilot Please address the CodeRabbit review feedback on this PR (1 inline comments).

Addressed in c3e7a85. Changed isSearching to derive from raw searchValue.trim().length > 0 so the CategoriesFilter and ListHeaderComponent hide/show instantly without the 400ms debounce lag. Added isQueryReady = debouncedSearchValue.trim().length > 0 to gate the vector results display — the loading spinner now shows both while the debounce is pending and while the vector fetch is in flight, then results render once both are ready.

@andrew-bierman
Copy link
Collaborator

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Mar 9, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

iOS – Catalog Search Overlay Shows "Showing X of Y Items" Label Peeking

2 participants