Skip to content

feat(ScrollArea): add getScrollElement virtualize option#6650

Merged
benjamincanac merged 2 commits into
nuxt:v4from
mikenewbon:feat/scroll-area-external-scroll-element
Jun 29, 2026
Merged

feat(ScrollArea): add getScrollElement virtualize option#6650
benjamincanac merged 2 commits into
nuxt:v4from
mikenewbon:feat/scroll-area-external-scroll-element

Conversation

@mikenewbon

@mikenewbon mikenewbon commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

🔗 Linked issue

Resolves #6649

❓ Type of change

  • 📖 Documentation (updates to the documentation or readme)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • 👌 Enhancement (improving an existing functionality)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

Exposes getScrollElement through the virtualize prop (previously hardcoded to the component's root and excluded from the type), so a list can virtualize against an ancestor scroll container. This lets surrounding content and the virtualized list share a single scrollbar instead of nesting a second scroller.

In external mode the root no longer owns a scroll viewport, item positions account for scrollMargin, and the resize observer tracks the real scroll element. Gated behind external mode, so default behaviour is unchanged (snapshots: additions only). Adds a docs example and a test case.

📝 Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

@github-actions github-actions Bot added the v4 #4488 label Jun 29, 2026
@mikenewbon
mikenewbon marked this pull request as draft June 29, 2026 02:49
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

ScrollAreaVirtualizeOptions gains an explicit getScrollElement?: () => Element | null field. The component’s virtualizer logic adds an isExternalScroll flag; when enabled, it uses the provided scroll element, subtracts scrollMargin from item positions, switches the root to overflow: visible, and updates resize tracking to follow the active scroll element. A new test covers getScrollElement returning document.body with scrollMargin: 20. A new ScrollAreaExternalScrollExample component and documentation subsection demonstrate the pattern.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description check ✅ Passed The description matches the implemented feature and documents the external-scroll mode and test/docs updates.
Linked Issues check ✅ Passed The PR exposes getScrollElement through virtualize, falls back to the root when unset, and keeps default behavior unchanged.
Out of Scope Changes check ✅ Passed All code, docs, and test changes are directly tied to the external-scroll virtualization feature.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title clearly and concisely describes the main change: adding a getScrollElement virtualization option to ScrollArea.
✨ 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.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 3

🧹 Nitpick comments (1)
test/components/ScrollArea.spec.ts (1)

25-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the scroll-margin positioning path too.

The current external-scroll case snapshots an empty viewport, so it doesn’t exercise the new virtualItem.start - scrollMargin transform logic. Add a measurable virtual item or mocked virtualizer geometry and assert the rendered transform.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/components/ScrollArea.spec.ts` at line 25, The external-scroll test case
in ScrollArea.spec.ts currently snapshots an empty viewport and never verifies
the `virtualItem.start - scrollMargin` positioning path. Update the virtualize
external scroll element scenario in the ScrollArea spec to use a measurable
virtual item or mocked virtualizer geometry, then assert the rendered transform
produced by the virtual item positioning logic so the scroll-margin adjustment
is exercised.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@docs/app/components/content/examples/scroll-area/ScrollAreaExternalScrollExample.vue`:
- Around line 10-15: The ScrollAreaExternalScrollExample.vue docs sample is
fetching live data from dummyjson.com via useLazyFetch, which makes the example
nondeterministic and exposes viewers to a third party. Replace the remote URL
with a checked-in fixture or other repo-hosted data source, and keep the
existing useLazyFetch transform/default flow in place so the example still
renders User data without depending on an external service.
- Around line 65-68: The scroll trigger in ScrollAreaExternalScrollExample
currently only watches query, so it can miss the first available match when
useLazyFetch resolves after typing. Update the watcher around scrollToMatch and
cursor handling to react to match availability, using currentMatch or matches as
the source of truth instead of only query changes, so the first hit is centered
as soon as results arrive.

In `@docs/content/docs/2.components/scroll-area.md`:
- Line 156: The docs heading still marks the external scroll element section as
upcoming with the Soon badge, which conflicts with this PR’s new feature. Update
the scroll-area documentation heading to remove the Soon badge from the “With
external scroll element” section so the published docs present it as available.
Use the existing scroll-area markdown section title as the anchor when editing.

---

Nitpick comments:
In `@test/components/ScrollArea.spec.ts`:
- Line 25: The external-scroll test case in ScrollArea.spec.ts currently
snapshots an empty viewport and never verifies the `virtualItem.start -
scrollMargin` positioning path. Update the virtualize external scroll element
scenario in the ScrollArea spec to use a measurable virtual item or mocked
virtualizer geometry, then assert the rendered transform produced by the virtual
item positioning logic so the scroll-margin adjustment is exercised.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ee422ae9-3610-4566-abb0-6e6cb6a8c3bd

📥 Commits

Reviewing files that changed from the base of the PR and between 3bf1a92 and 3265cc4.

⛔ Files ignored due to path filters (2)
  • test/components/__snapshots__/ScrollArea-vue.spec.ts.snap is excluded by !**/*.snap
  • test/components/__snapshots__/ScrollArea.spec.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (4)
  • docs/app/components/content/examples/scroll-area/ScrollAreaExternalScrollExample.vue
  • docs/content/docs/2.components/scroll-area.md
  • src/runtime/components/ScrollArea.vue
  • test/components/ScrollArea.spec.ts

Comment thread docs/content/docs/2.components/scroll-area.md
@pkg-pr-new

pkg-pr-new Bot commented Jun 29, 2026

Copy link
Copy Markdown
npm i https://pkg.pr.new/@nuxt/ui@6650

commit: 07bbf82

@mikenewbon

Copy link
Copy Markdown
Contributor Author
image

@mikenewbon
mikenewbon marked this pull request as ready for review June 29, 2026 03:27

@coderabbitai coderabbitai Bot left a comment

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.

♻️ Duplicate comments (1)
docs/content/docs/2.components/scroll-area.md (1)

156-156: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the Soon badge from the external scroll element section.

This section documents a feature introduced by this PR. Keeping the Soon badge incorrectly signals to readers that the feature is not yet available.

-### With external scroll element :badge{label="Soon" class="align-text-top"}
+### With external scroll element
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/content/docs/2.components/scroll-area.md` at line 156, Remove the Soon
badge from the external scroll element section heading in the scroll-area docs,
since this PR already introduces the feature. Update the heading text in the
Markdown content so the section title no longer includes the badge markup, and
keep the rest of the documentation unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@docs/content/docs/2.components/scroll-area.md`:
- Line 156: Remove the Soon badge from the external scroll element section
heading in the scroll-area docs, since this PR already introduces the feature.
Update the heading text in the Markdown content so the section title no longer
includes the badge markup, and keep the rest of the documentation unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 070e8bf3-fab5-4558-afc5-072fd8e1e694

📥 Commits

Reviewing files that changed from the base of the PR and between 3265cc4 and 249ccd5.

⛔ Files ignored due to path filters (2)
  • test/components/__snapshots__/ScrollArea-vue.spec.ts.snap is excluded by !**/*.snap
  • test/components/__snapshots__/ScrollArea.spec.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (4)
  • docs/app/components/content/examples/scroll-area/ScrollAreaExternalScrollExample.vue
  • docs/content/docs/2.components/scroll-area.md
  • src/runtime/components/ScrollArea.vue
  • test/components/ScrollArea.spec.ts
✅ Files skipped from review due to trivial changes (1)
  • test/components/ScrollArea.spec.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/runtime/components/ScrollArea.vue
  • docs/app/components/content/examples/scroll-area/ScrollAreaExternalScrollExample.vue

Allow passing `getScrollElement` through the `virtualize` prop so the list
virtualizes against an ancestor scroll container instead of the component's
own root — letting surrounding content and the virtualized list share a
single scrollbar. Pair with `scrollMargin` for the list's offset within the
scroll element. The root no longer creates its own scroll viewport in this
mode, item positions account for `scrollMargin`, and the resize observer
tracks the actual scroll viewport. Adds a docs example.

Resolves nuxt#6649.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@benjamincanac benjamincanac left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks @mikenewbon! 😊 Do you think we should do this in Table as well?

@benjamincanac benjamincanac changed the title feat(ScrollArea): support an external scroll element for virtualization feat(ScrollArea): add getScrollElement virtualize option Jun 29, 2026
@benjamincanac
benjamincanac merged commit a84de85 into nuxt:v4 Jun 29, 2026
20 checks passed
@mikenewbon

Copy link
Copy Markdown
Contributor Author

Cool idea @benjamincanac - I will open an issue/pr

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

Labels

v4 #4488

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ScrollArea: expose getScrollElement for virtualization

2 participants