feat(scroll-area): add contentProps to ScrollArea.ViewportFeat/scroll area content props#3810
Open
resdust wants to merge 4 commits intoradix-ui:mainfrom
Open
feat(scroll-area): add contentProps to ScrollArea.ViewportFeat/scroll area content props#3810resdust wants to merge 4 commits intoradix-ui:mainfrom
contentProps to ScrollArea.ViewportFeat/scroll area content props#3810resdust wants to merge 4 commits intoradix-ui:mainfrom
Conversation
Add a `contentProps` prop to `ScrollAreaViewport` that allows consumers
to pass attributes (including style overrides) to the internal content
wrapper `div`.
The content wrapper uses `display: table` by default to ensure accurate
scroll width/height measurement for thumb sizing. However, this can
conflict with common layout patterns (e.g. flex columns in chat lists,
vertical-only scroll containers) where `display: table` causes children
to overflow their container width.
With `contentProps`, consumers can now override the display mode without
resorting to `!important` in CSS:
```tsx
<ScrollArea.Viewport
contentProps={{ style: { display: 'flex', flexDirection: 'column' } }}
>
{children}
</ScrollArea.Viewport>
```
The default styles (`minWidth: '100%'`, `display: 'table'`) are preserved
as base values and can be selectively overridden via `contentProps.style`.
Verify that the new contentProps prop correctly forwards attributes (style, className, data-*) to the internal content wrapper div, and that base styles (minWidth, display) are preserved or overridable. Co-authored-by: Cursor <cursoragent@cursor.com>
🦋 Changeset detectedLatest commit: 9a0051f The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
ScrollArea.Viewportrenders an internal<div>wrapper around its children with an inline style ofdisplay: table; min-width: 100%. This is intentional — the table layout ensures accurate content size measurement for scrollbar thumb sizing.However, this forces a table layout on all consumers, which conflicts with common patterns like flex or grid layouts. Today the only workaround is
!importantin CSS, which is fragile and goes against styling best practices.This PR adds a
contentPropsprop toScrollArea.Viewportthat forwards attributes to the internal content wrapper<div>, allowing consumers to overridedisplay(and other props) cleanly:<ScrollArea.Viewport
contentProps={{
style: { display: 'flex', flexDirection: 'column' },
className: 'my-content',
}}
{children}
</ScrollArea.Viewport>
Style merging strategy: base styles (minWidth: 100%, display: table) are applied first, then contentProps.style spreads on top — so consumers can selectively override only what they need while the rest is preserved.
Checklist
[x] Code change in packages/react/scroll-area/src/scroll-area.tsx
[x] Tests added in packages/react/scroll-area/src/scroll-area.test.tsx (8 tests, all passing)
[x] Storybook example added (ContentProps story) comparing default vs overridden layout
[x] JSDoc with usage notes and caveats on the new prop
[x] No breaking changes — contentProps is optional, defaults to undefined
Test plan
pnpm test— 8 new tests covering:pnpm dev— StorybookContentPropsstory shows side-by-side comparison