Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "[ScrollArea] Viewport fixes (#2945)" #3225

Merged
merged 1 commit into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .yarn/versions/6cbc86b8.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
releases:
"@radix-ui/react-scroll-area": patch

declined:
- primitives
- ssr-testing
88 changes: 0 additions & 88 deletions packages/react/scroll-area/src/ScrollArea.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -307,94 +307,6 @@ export const Chromatic = () => (
);
Chromatic.parameters = { chromatic: { disable: false } };

export const ChromaticEllipsis = () => (
<>
<h1>Ellipsis at viewport width</h1>
<ScrollAreaStory type="always" horizontal={false} vertical>
{Array.from({ length: 10 }).map((_, index) => (
<Copy
key={index}
style={{
maxWidth: '100%',
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
}}
/>
))}
</ScrollAreaStory>

<h1>Ellipsis at content width</h1>
<ScrollAreaStory type="always" horizontal vertical>
{Array.from({ length: 10 }).map((_, index) => (
<Copy
key={index}
style={{
width: 500,
overflow: 'hidden',
whiteSpace: 'nowrap',
textOverflow: 'ellipsis',
}}
/>
))}
</ScrollAreaStory>
</>
);
ChromaticEllipsis.parameters = { chromatic: { disable: false } };

const COPY_SHORT = `
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sit amet eros iaculis,
bibendum tellus ac, lobortis odio. Aliquam bibendum elit est, in iaculis est commodo id.
Donec pulvinar est libero. Proin consectetur pellentesque molestie.
`;

export const ChromaticFillParentHeight = () => (
<>
<h1>Parent has fixed height, short content</h1>
<div style={{ display: 'flex', width: 600, height: 300, overflow: 'hidden' }}>
<ScrollAreaStory type="always" vertical horizontal style={{ width: '50%', height: 'auto' }}>
<div>{COPY_SHORT}</div>
</ScrollAreaStory>
<ScrollAreaStory type="always" vertical horizontal style={{ width: '50%', height: 'auto' }}>
<div>{COPY_SHORT}</div>
</ScrollAreaStory>
</div>

<h1>Parent has fixed height, tall content</h1>
<div style={{ display: 'flex', width: 600, height: 300, overflow: 'hidden' }}>
<ScrollAreaStory type="always" vertical horizontal style={{ width: '50%', height: 'auto' }}>
<div>{COPY_SHORT}</div>
</ScrollAreaStory>
<ScrollAreaStory type="always" vertical horizontal style={{ width: '50%', height: 'auto' }}>
<Copy style={{ width: 'auto' }} />
</ScrollAreaStory>
</div>

<h1>Parent has max height</h1>
<div style={{ display: 'flex', width: 600, maxHeight: 300, overflow: 'hidden' }}>
<ScrollAreaStory type="always" vertical horizontal style={{ width: '50%', height: 'auto' }}>
<div>{COPY_SHORT}</div>
</ScrollAreaStory>
<ScrollAreaStory type="always" vertical horizontal style={{ width: '50%', height: 'auto' }}>
<Copy style={{ width: 'auto' }} />
</ScrollAreaStory>
</div>

<h1>Parent has auto height</h1>
<div style={{ display: 'flex', width: 600, overflow: 'hidden' }}>
<ScrollAreaStory type="always" vertical horizontal style={{ width: '50%', height: 'auto' }}>
<div>{COPY_SHORT}</div>
</ScrollAreaStory>
<ScrollAreaStory type="always" vertical horizontal style={{ width: '50%', height: 'auto' }}>
<Copy style={{ width: 'auto' }} />
</ScrollAreaStory>
</div>

<div style={{ height: 200 }} />
</>
);
ChromaticFillParentHeight.parameters = { chromatic: { disable: false } };

const DYNAMIC_CONTENT_DELAY = 2000;

export const ChromaticDynamicContentBeforeLoaded = () => {
Expand Down
69 changes: 13 additions & 56 deletions packages/react/scroll-area/src/ScrollArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,39 +141,22 @@ interface ScrollAreaViewportProps extends PrimitiveDivProps {

const ScrollAreaViewport = React.forwardRef<ScrollAreaViewportElement, ScrollAreaViewportProps>(
(props: ScopedProps<ScrollAreaViewportProps>, forwardedRef) => {
const { __scopeScrollArea, children, asChild, nonce, ...viewportProps } = props;
const { __scopeScrollArea, children, nonce, ...viewportProps } = props;
const context = useScrollAreaContext(VIEWPORT_NAME, __scopeScrollArea);
const ref = React.useRef<ScrollAreaViewportElement>(null);
const composedRefs = useComposedRefs(forwardedRef, ref, context.onViewportChange);
return (
<>
{/* Hide scrollbars cross-browser and enable momentum scroll for touch devices */}
<style
dangerouslySetInnerHTML={{
__html: `
[data-radix-scroll-area-viewport] {
scrollbar-width: none;
-ms-overflow-style: none;
-webkit-overflow-scrolling: touch;
}
[data-radix-scroll-area-viewport]::-webkit-scrollbar {
display: none;
}
:where([data-radix-scroll-area-viewport]) {
display: flex;
flex-direction: column;
align-items: stretch;
}
:where([data-radix-scroll-area-content]) {
flex-grow: 1;
}
`,
__html: `[data-radix-scroll-area-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-scroll-area-viewport]::-webkit-scrollbar{display:none}`,
}}
nonce={nonce}
/>
<Primitive.div
data-radix-scroll-area-viewport=""
{...viewportProps}
asChild={asChild}
ref={composedRefs}
style={{
/**
Expand All @@ -192,22 +175,16 @@ const ScrollAreaViewport = React.forwardRef<ScrollAreaViewportElement, ScrollAre
...props.style,
}}
>
{getSubtree({ asChild, children }, (children) => (
<div
data-radix-scroll-area-content=""
ref={context.onContentChange}
/**
* When horizontal scrollbar is visible: this element should be at least
* as wide as its children for size calculations to work correctly.
*
* When horizontal scrollbar is NOT visible: this element's width should
* be constrained by the parent container to enable `text-overflow: ellipsis`
*/
style={{ minWidth: context.scrollbarXEnabled ? 'fit-content' : undefined }}
>
{children}
</div>
))}
{/**
* `display: table` ensures our content div will match the size of its children in both
* horizontal and vertical axis so we can determine if scroll width/height changed and
* recalculate thumb sizes. This doesn't account for children with *percentage*
* widths that change. We'll wait to see what use-cases consumers come up with there
* before trying to resolve it.
*/}
<div ref={context.onContentChange} style={{ minWidth: '100%', display: 'table' }}>
{children}
</div>
</Primitive.div>
</>
);
Expand Down Expand Up @@ -1032,26 +1009,6 @@ function useResizeObserver(element: HTMLElement | null, onResize: () => void) {
}, [element, handleResize]);
}

/**
* This is a helper function that is used when a component supports `asChild`
* using the `Slot` component but its implementation contains nested DOM elements.
*
* Using it ensures if a consumer uses the `asChild` prop, the elements are in
* correct order in the DOM, adopting the intended consumer `children`.
*/
function getSubtree(
options: { asChild: boolean | undefined; children: React.ReactNode },
content: React.ReactNode | ((children: React.ReactNode) => React.ReactNode)
) {
const { asChild, children } = options;
if (!asChild) return typeof content === 'function' ? content(children) : content;

const firstChild = React.Children.only(children) as React.ReactElement;
return React.cloneElement(firstChild, {
children: typeof content === 'function' ? content(firstChild.props.children) : content,
});
}

/* -----------------------------------------------------------------------------------------------*/

const Root = ScrollArea;
Expand Down
66 changes: 18 additions & 48 deletions ssr-testing/app/scroll-area/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,57 +9,27 @@ import {

export default function Page() {
return (
<div>
<ScrollArea>
<Scrollbar orientation="vertical">
<ScrollAreaThumb />
</Scrollbar>
<ScrollArea style={{ width: '400px', height: '400px' }}>
<Scrollbar orientation="vertical">
<ScrollAreaThumb />
</Scrollbar>

<Scrollbar orientation="horizontal">
<ScrollAreaThumb />
</Scrollbar>
<Scrollbar orientation="horizontal">
<ScrollAreaThumb />
</Scrollbar>

<ScrollAreaViewport style={{ width: '400px', height: '400px' }}>
<div style={{ width: '2000px', padding: 20 }}>
<LongContent />
<LongContent />
<LongContent />
<LongContent />
<LongContent />
<LongContent />
<LongContent />
</div>
</ScrollAreaViewport>
<ScrollAreaViewport style={{ width: '2000px', padding: 20 }}>
<LongContent />
<LongContent />
<LongContent />
<LongContent />
<LongContent />
<LongContent />
<LongContent />
</ScrollAreaViewport>

<ScrollAreaCorner />
</ScrollArea>

<ScrollArea>
<Scrollbar orientation="vertical">
<ScrollAreaThumb />
</Scrollbar>

<Scrollbar orientation="horizontal">
<ScrollAreaThumb />
</Scrollbar>

<ScrollAreaViewport style={{ width: '400px', height: '400px' }} asChild>
<section style={{ border: '1px solid' }}>
<div style={{ width: '2000px', padding: 20 }}>
<LongContent />
<LongContent />
<LongContent />
<LongContent />
<LongContent />
<LongContent />
<LongContent />
</div>
</section>
</ScrollAreaViewport>

<ScrollAreaCorner />
</ScrollArea>
</div>
<ScrollAreaCorner />
</ScrollArea>
);
}

Expand Down
Loading