Skip to content

fix(ui): improve search page UX#2115

Open
ShroXd wants to merge 8 commits intonpmx-dev:mainfrom
ShroXd:optimize-searching-page-ux
Open

fix(ui): improve search page UX#2115
ShroXd wants to merge 8 commits intonpmx-dev:mainfrom
ShroXd:optimize-searching-page-ux

Conversation

@ShroXd
Copy link
Contributor

@ShroXd ShroXd commented Mar 17, 2026

🔗 Linked issue

Resolves #2112

🧭 Context

As the linked issue mentioned, the search page layout shifts too much during typing, which is not a good user experience.

📚 Description

Several UX improvements to the search page.

  1. Add debounce to searching, the delay is 250ms, same value as updateUrlQuery.
  2. Tweak transition animation binding on the element to prevent flicker during searching.
  3. Improve calculation logic of showClaimPrompt to make the behavior more intuitive.
  4. Add transition to suggestion area to improve the user experience.
Screen.Recording.2026-03-17.at.14.24.18.mov

@vercel
Copy link

vercel bot commented Mar 17, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Mar 19, 2026 9:12am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Mar 19, 2026 9:12am
npmx-lunaria Ignored Ignored Mar 19, 2026 9:12am

Request Review

@ShroXd ShroXd force-pushed the optimize-searching-page-ux branch from da441a1 to 233afd6 Compare March 17, 2026 05:30
@ShroXd ShroXd changed the title Optimize searching page ux fix(search): improve search page UX Mar 17, 2026
@codecov
Copy link

codecov bot commented Mar 17, 2026

Codecov Report

❌ Patch coverage is 50.00000% with 3 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
app/composables/useGlobalSearch.ts 50.00% 3 Missing ⚠️

📢 Thoughts on this report? Let us know!

@ShroXd ShroXd changed the title fix(search): improve search page UX fix(ui): improve search page UX Mar 17, 2026
@ShroXd ShroXd marked this pull request as ready for review March 17, 2026 06:35
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 17, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: dfaae2ef-0224-40a2-b6d5-000f16930257

📥 Commits

Reviewing files that changed from the base of the PR and between bee7094 and 5e80824.

📒 Files selected for processing (3)
  • app/components/Package/List.vue
  • app/composables/useGlobalSearch.ts
  • app/pages/search.vue
✅ Files skipped from review due to trivial changes (1)
  • app/components/Package/List.vue
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/pages/search.vue

📝 Walkthrough

Walkthrough

This PR adds a reactive newSearchBatchSize threshold to Package List rendering to limit which items receive staggered enter animations (items with index >= newSearchBatchSize), resets that threshold when a new search result set arrives, and adjusts per-item animation delays accordingly. In useGlobalSearch.ts it introduces SEARCH_DEBOUNCE_MS (100ms), a debounced commitSearchQuery with cancel/flush integration, and uses it for instantSearch and URL-update debouncing. In search.vue the showClaimPrompt computed is refactored with early returns, suggestion lists are wrapped in Transition, and the claim button gains disabled handling during pending status.

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description relates to the changeset by outlining four specific UX improvements to the search page, all corresponding to file changes.
Linked Issues check ✅ Passed The code changes address the linked issue #2112 by debouncing search queries, preventing layout shifts with improved animation bindings, stabilising claim prompt visibility, and adding transitions to suggestions.
Out of Scope Changes check ✅ Passed All changes in the three modified files (Package/List.vue, useGlobalSearch.ts, search.vue) directly address the objectives from #2112 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
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Tip

CodeRabbit can use Trivy to scan for security misconfigurations and secrets in Infrastructure as Code files.

Add a .trivyignore file to your project to customize which findings Trivy reports.

Copy link
Contributor

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/components/Package/List.vue (1)

122-133: ⚠️ Potential issue | 🟠 Major

Handle empty→non-empty results as a new-search reset.

At Line 129, the reset condition skips the oldResults.length === 0 && newResults.length > 0 transition. That leaves newSearchBatchSize stale (often Infinity or 0) and breaks the intended animation split for subsequent appended items.

💡 Proposed fix
 watch(
   () => props.results,
   (newResults, oldResults) => {
     // If this looks like a new search (different first item or much shorter), reset
     if (
       !oldResults ||
+      oldResults.length === 0 ||
       newResults.length === 0 ||
-      (oldResults.length > 0 && newResults[0]?.package.name !== oldResults[0]?.package.name)
+      newResults[0]?.package.name !== oldResults[0]?.package.name
     ) {
       hasScrolledToInitial.value = false
       newSearchBatchSize.value = newResults.length
     }
   },
 )
🧹 Nitpick comments (1)
app/components/Package/List.vue (1)

182-190: Consider extracting the repeated animation binding into a helper.

The same :class/:style animation logic is duplicated in both card branches. A small helper/computed would reduce drift risk when tuning animation behaviour later.

Also applies to: 241-249


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3beedd05-2a22-4856-a16f-47aed15ba65e

📥 Commits

Reviewing files that changed from the base of the PR and between 8ee186a and 1e89802.

📒 Files selected for processing (3)
  • app/components/Package/List.vue
  • app/composables/useGlobalSearch.ts
  • app/pages/search.vue

@pauliecodes
Copy link
Contributor

Tested this locally and the search debounce and the layout shift fixes for the Claim button work really well. LGTM!

@MatteoGabriele
Copy link
Contributor

MatteoGabriele commented Mar 18, 2026

I think it might be more effective to fix this with a different UI rather than using a complex debounce system. I can really feel the lag compared to our current setup, and since we prioritize speed, it might be worth approaching this from a different perspective.

@alexdln shared the Figma file yesterday, and I noticed a different layout on most pages: maybe moving the package claim and the owner to the column is the right move here. What do you think?

Screenshot 2026-03-18 at 14 46 33

@alexdln
Copy link
Member

alexdln commented Mar 18, 2026

If this works, it will be useful in any case, since on the sidebar in the future there may be 2 and more cards - f.e. user and organization

(but sorry, I'm not sure I understand the solution and can't properly review it, but result lgtm)

@ShroXd ShroXd force-pushed the optimize-searching-page-ux branch from bee7094 to 5e80824 Compare March 19, 2026 09:10
@ShroXd
Copy link
Contributor Author

ShroXd commented Mar 19, 2026

@MatteoGabriele Thanks for pointing it out. Actually, the major part of this fix is the conditional transition animation on the list, not the debounce. I added the debounce to make the deletion experience better — when users delete characters by pressing keys quickly, without debounce the list would change immediately and cause a flickering effect. If the lag feels too noticeable, I've reduced SEARCH_DEBOUNCE_MS to 100ms in the latest commit — feel free to give it a try and let me know how it feels!

On the other hand, the new layout looks awesome! However, on small-screen devices, a one-column layout is the only option, which brings us back to the original problem of handling the flickering suggestions area. So I think it's still necessary to do something to improve it.

@alexdln Thanks for reviewing. Could you point out which part of the code is confusing to you? It might be a good signal for me to improve the implementation or add some comments to explain it.

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.

Layout moves too much when typing in the search bar

4 participants