feat(ScrollArea): add getScrollElement virtualize option#6650
Conversation
📝 WalkthroughWalkthrough
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
test/components/ScrollArea.spec.ts (1)
25-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAssert the scroll-margin positioning path too.
The current external-scroll case snapshots an empty viewport, so it doesn’t exercise the new
virtualItem.start - scrollMargintransform 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
⛔ Files ignored due to path filters (2)
test/components/__snapshots__/ScrollArea-vue.spec.ts.snapis excluded by!**/*.snaptest/components/__snapshots__/ScrollArea.spec.ts.snapis excluded by!**/*.snap
📒 Files selected for processing (4)
docs/app/components/content/examples/scroll-area/ScrollAreaExternalScrollExample.vuedocs/content/docs/2.components/scroll-area.mdsrc/runtime/components/ScrollArea.vuetest/components/ScrollArea.spec.ts
commit: |
3265cc4 to
249ccd5
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
docs/content/docs/2.components/scroll-area.md (1)
156-156: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winRemove the
Soonbadge from the external scroll element section.This section documents a feature introduced by this PR. Keeping the
Soonbadge 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
⛔ Files ignored due to path filters (2)
test/components/__snapshots__/ScrollArea-vue.spec.ts.snapis excluded by!**/*.snaptest/components/__snapshots__/ScrollArea.spec.ts.snapis excluded by!**/*.snap
📒 Files selected for processing (4)
docs/app/components/content/examples/scroll-area/ScrollAreaExternalScrollExample.vuedocs/content/docs/2.components/scroll-area.mdsrc/runtime/components/ScrollArea.vuetest/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>
249ccd5 to
a58120d
Compare
benjamincanac
left a comment
There was a problem hiding this comment.
Thanks @mikenewbon! 😊 Do you think we should do this in Table as well?
getScrollElement virtualize option
|
Cool idea @benjamincanac - I will open an issue/pr |

🔗 Linked issue
Resolves #6649
❓ Type of change
📚 Description
Exposes
getScrollElementthrough thevirtualizeprop (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