Skip to content

feat: enter key open the first package when searching#993

Merged
danielroe merged 3 commits intonpmx-dev:mainfrom
kalu5:feat/#916
Feb 5, 2026
Merged

feat: enter key open the first package when searching#993
danielroe merged 3 commits intonpmx-dev:mainfrom
kalu5:feat/#916

Conversation

@kalu5
Copy link
Contributor

@kalu5 kalu5 commented Feb 5, 2026

feat #916

@vercel
Copy link

vercel bot commented Feb 5, 2026

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

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

Request Review

@codecov
Copy link

codecov bot commented Feb 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 5, 2026

📝 Walkthrough

Walkthrough

Keyboard-driven navigation for search results was added. A programmatic navigateToPackage was introduced, along with a pendingEnterQuery state to hold an Enter-typed query pending asynchronous results. handleResultsKeydown was changed to immediately navigate when Enter is pressed and the top result exactly matches the input; otherwise it stores the input in pendingEnterQuery. A watcher on displayResults triggers navigation when results arrive and the first result matches the pending query. The Enter-key flow now prefers immediate navigation for exact matches and falls back to deferred navigation via the watcher for async results.

🚥 Pre-merge checks | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Description check ❓ Inconclusive The pull request description 'feat #916' is minimal but directly references a feature issue and relates to the changeset of keyboard-driven navigation for search results. Expand the description to explain what feature #916 implements, why it was changed, and how the Enter key behaviour now works for users.

✏️ 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

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

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

🧹 Nitpick comments (1)
app/pages/search.vue (1)

560-583: Avoid overlapping polling timers on repeated Enter presses.

Each Enter press starts a new interval/timeout pair. If users press Enter multiple times quickly, timers stack and keep resetting the debounced navigation. Consider reusing a single timer pair.

Proposed refactor
+let waitSearchResultInterval: ReturnType<typeof setInterval> | null = null
+let waitSearchResultTimeout: ReturnType<typeof setTimeout> | null = null
+
+function clearSearchResultTimers() {
+  if (waitSearchResultInterval) clearInterval(waitSearchResultInterval)
+  if (waitSearchResultTimeout) clearTimeout(waitSearchResultTimeout)
+  waitSearchResultInterval = null
+  waitSearchResultTimeout = null
+}
+
 function handleResultsKeydown(e: KeyboardEvent) {
   // If the active element is an input and there are results, navigate to the first result
   if (e.key === 'Enter' && document.activeElement?.tagName === 'INPUT') {
+    clearSearchResultTimers()
     // After entering quickly and pressing Enter, find the latest packages
     const latestPackageName = findLatestPackageName()
     // Find successful . navigate to package page
     if (latestPackageName) return navigateToPackage(latestPackageName)
     // Waiting for the latest search results (maximum 1.5 seconds)
-    let waitSearchResultInterval: ReturnType<typeof setInterval> | null
-    function clearSearchResultInterval() {
-      if (waitSearchResultInterval) clearInterval(waitSearchResultInterval)
-      waitSearchResultInterval = null
-    }
     waitSearchResultInterval = setInterval(() => {
       const latestPackageName = findLatestPackageName()
       if (latestPackageName) {
-        clearSearchResultInterval()
+        clearSearchResultTimers()
         return navigateToPackage(latestPackageName)
       }
     }, 100)
 
-    setTimeout(() => {
-      clearSearchResultInterval()
-    }, 1500)
+    waitSearchResultTimeout = setTimeout(() => {
+      clearSearchResultTimers()
+    }, 1500)
   }

Comment on lines 544 to 549
// Find latest package name
function findLatestPackageName() {
const packageName = displayResults.value?.[0]?.package.name
if (packageName === query.value) {
return packageName.split('/')
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Normalise query comparison to avoid missing exact matches.

The comparison is case‑sensitive and doesn’t trim whitespace, so typing “React ” won’t navigate even if the top result is the exact package.

Proposed fix
 function findLatestPackageName() {
-  const packageName = displayResults.value?.[0]?.package.name
-  if (packageName === query.value) {
+  const packageName = displayResults.value?.[0]?.package?.name
+  const q = query.value.trim().toLowerCase()
+  if (packageName && packageName.toLowerCase() === q) {
     return packageName.split('/')
   }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Find latest package name
function findLatestPackageName() {
const packageName = displayResults.value?.[0]?.package.name
if (packageName === query.value) {
return packageName.split('/')
}
// Find latest package name
function findLatestPackageName() {
const packageName = displayResults.value?.[0]?.package?.name
const q = query.value.trim().toLowerCase()
if (packageName && packageName.toLowerCase() === q) {
return packageName.split('/')
}
}

@danielroe danielroe changed the title feat: enter key open the first package when searching (#916) feat: enter key open the first package when searching Feb 5, 2026
@danielroe danielroe added this pull request to the merge queue Feb 5, 2026
Merged via the queue into npmx-dev:main with commit f4c6488 Feb 5, 2026
16 checks passed
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.

2 participants