Skip to content

fix: migrate live region to useAnnouncer#2267

Closed
RYGRIT wants to merge 2 commits intonpmx-dev:mainfrom
RYGRIT:fix/follow-up-1812
Closed

fix: migrate live region to useAnnouncer#2267
RYGRIT wants to merge 2 commits intonpmx-dev:mainfrom
RYGRIT:fix/follow-up-1812

Conversation

@RYGRIT
Copy link
Copy Markdown
Contributor

@RYGRIT RYGRIT commented Mar 25, 2026

🔗 Linked issue

follow up #1812

🧭 Context

nuxt/nuxt#34318

📚 Description

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 25, 2026

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

Project Deployment Actions Updated (UTC)
docs.npmx.dev Error Error Mar 25, 2026 3:33am
npmx.dev Error Error Mar 25, 2026 3:33am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
npmx-lunaria Ignored Ignored Mar 25, 2026 3:33am

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 25, 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: c2ad555a-90a2-47ab-a549-06afcbaa3f2d

📥 Commits

Reviewing files that changed from the base of the PR and between c551e62 and 218390e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (1)
  • package.json
✅ Files skipped from review due to trivial changes (1)
  • package.json

📝 Walkthrough

Walkthrough

This PR updates package.json to bump nuxt from 4.3.1 to 4.4.2, adds a global <NuxtAnnouncer /> to app/app.vue, and replaces the search page's DOM-based debounced live-region with useAnnouncer().polite(...). The search page now uses two debounced announcers (250ms desktop, 700ms mobile), cancels pending announcements on unmount, suppresses announcements while status === 'pending', and cancels announcements when searches return no results. No exported/public API signatures were changed.

Possibly related PRs

Suggested labels

needs review

Suggested reviewers

  • knowler
  • danielroe
🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description directly references linked issue #1812 and Nuxt upstream PR #34318, clearly indicating this is a follow-up to migrate live regions to useAnnouncer—which aligns with the file changes migrating from role='status' to the useAnnouncer API.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Copy link
Copy Markdown
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


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 20736aaf-604e-454d-9239-3f38ee2d4368

📥 Commits

Reviewing files that changed from the base of the PR and between eced357 and c551e62.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • app/app.vue
  • app/pages/search.vue
  • package.json

Comment on lines +620 to +669
() => ({
rateLimited: isRateLimited.value,
searchStatus: status.value,
count: displayResults.value.length,
searchQuery: query.value,
mode: viewMode.value,
pagMode: paginationMode.value,
total: effectiveTotal.value,
}),
({ rateLimited, searchStatus, count, searchQuery, mode, pagMode, total }) => {
if (rateLimited) {
announcePolite($t('search.rate_limited'))
return
}

if (isMobile.value) {
updateLiveRegionDesktop.cancel()
updateLiveRegionMobile(newVal)
} else {
updateLiveRegionMobile.cancel()
updateLiveRegionDesktop(newVal)
// Don't announce while searching
if (searchStatus === 'pending') {
cancelPendingAnnouncements()
return
}

if (count > 0) {
if (mode === 'table' || pagMode === 'paginated') {
const pSize = Math.min(preferredPageSize.value, total)

announcePolite(
$t(
'filters.count.showing_paginated',
{
pageSize: pSize.toString(),
count: $n(total),
},
total,
),
)
} else if (isRelevanceSort.value) {
announcePolite(
$t(
'search.found_packages',
{ count: $n(visibleResults.value?.total ?? 0) },
visibleResults.value?.total ?? 0,
),
)
} else {
announcePolite($t('search.found_packages_sorted', { count: $n(total) }, total))
}
} else if (searchStatus === 'success' || searchStatus === 'error') {
if (searchQuery) {
announcePolite($t('search.no_results', { query: searchQuery }))
} else {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Watch the committed search state here, not the raw input.

Line 624 watches query.value, but the results come from committedQuery. When instant search is off, typing a new term can re-announce counts or “no results” for the previous result set. Lines 643 and 655 also read preferredPageSize.value and isRelevanceSort.value, but neither is in the source object, so page-size-only or sort-only changes can miss an announcement.

💡 Proposed fix
 watch(
   () => ({
     rateLimited: isRateLimited.value,
     searchStatus: status.value,
     count: displayResults.value.length,
-    searchQuery: query.value,
+    searchQuery: committedQuery.value,
     mode: viewMode.value,
     pagMode: paginationMode.value,
+    isRelevanceSort: isRelevanceSort.value,
+    pageSize: preferredPageSize.value,
     total: effectiveTotal.value,
   }),
-  ({ rateLimited, searchStatus, count, searchQuery, mode, pagMode, total }) => {
+  ({ rateLimited, searchStatus, count, searchQuery, mode, pagMode, isRelevanceSort, pageSize, total }) => {
     if (rateLimited) {
       announcePolite($t('search.rate_limited'))
       return
     }

     if (searchStatus === 'pending') {
       cancelPendingAnnouncements()
       return
     }

     if (count > 0) {
       if (mode === 'table' || pagMode === 'paginated') {
-        const pSize = Math.min(preferredPageSize.value, total)
+        const pSize = Math.min(pageSize, total)

         announcePolite(
           $t(
             'filters.count.showing_paginated',
             {
               pageSize: pSize.toString(),
               count: $n(total),
             },
             total,
           ),
         )
-      } else if (isRelevanceSort.value) {
+      } else if (isRelevanceSort) {
         announcePolite(
           $t(
             'search.found_packages',
             { count: $n(visibleResults.value?.total ?? 0) },
             visibleResults.value?.total ?? 0,

@ghostdevv
Copy link
Copy Markdown
Contributor

Did you close this because our Nuxt version isn't new enough (I think)? Or another reason? @RYGRIT

@RYGRIT
Copy link
Copy Markdown
Contributor Author

RYGRIT commented Mar 25, 2026

Did you close this because our Nuxt version isn't new enough (I think)? Or another reason? @RYGRIT

@ghostdevv My failure to synchronize the code in a timely manner caused a conflict in the pnpm-lock file. After merging, this triggered all CI errors. Therefore, I plan to resubmit the PR.

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