chore: remove horizontal wheel scrolling (#26332)

This commit is contained in:
Jaayden Halko
2026-06-12 16:09:13 +01:00
committed by GitHub
parent dd7d2653ca
commit 3184ed9e9e
3 changed files with 2 additions and 64 deletions
@@ -3,7 +3,6 @@
* @see {@link https://ui.shadcn.com/docs/components/scroll-area}
*/
import { ScrollArea as ScrollAreaPrimitive } from "radix-ui";
import { useEffect, useRef } from "react";
import { cn } from "#/utils/cn";
interface ScrollAreaProps
@@ -29,32 +28,12 @@ export const ScrollArea: React.FC<ScrollAreaProps> = ({
children,
...props
}) => {
const viewportRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const el = viewportRef.current;
if (!el || orientation === "vertical") return;
const handleWheel = (e: WheelEvent) => {
if (Math.abs(e.deltaY) <= Math.abs(e.deltaX)) return;
if (el.scrollWidth <= el.clientWidth) return;
if (el.scrollHeight > el.clientHeight) return;
const maxLeft = el.scrollWidth - el.clientWidth;
if (e.deltaY > 0 && el.scrollLeft >= maxLeft) return;
if (e.deltaY < 0 && el.scrollLeft <= 0) return;
e.preventDefault();
el.scrollBy({ left: e.deltaY, behavior: "smooth" });
};
el.addEventListener("wheel", handleWheel, { passive: false });
return () => el.removeEventListener("wheel", handleWheel);
}, [orientation]);
return (
<ScrollAreaPrimitive.Root
className={cn("relative overflow-hidden", className)}
{...props}
>
<ScrollAreaPrimitive.Viewport
ref={viewportRef}
tabIndex={viewportTabIndex}
className={cn("h-full w-full rounded-[inherit]", viewportClassName)}
>
@@ -151,46 +151,11 @@ export const LongLineFencedBlock: Story = {
if (!viewport) {
throw new Error("Expected a horizontally scrollable viewport.");
}
viewport.dispatchEvent(
new WheelEvent("wheel", { deltaY: 200, bubbles: true, cancelable: true }),
);
viewport.scrollLeft = 200;
await waitFor(() => expect(viewport.scrollLeft).toBeGreaterThan(0));
},
};
export const LongLineFencedBlockWheelEdges: Story = {
args: {
children: longLineCodeBlockMarkdown,
},
play: async ({ canvasElement }) => {
await expectCodeBlock(canvasElement, /apiUrl/);
const viewport = [
...canvasElement.querySelectorAll<HTMLElement>(
"[data-radix-scroll-area-viewport]",
),
].find((v) => v.scrollWidth > v.clientWidth);
if (!viewport) {
throw new Error("Expected a horizontally scrollable viewport.");
}
const dispatchWheel = (deltaY: number) => {
const event = new WheelEvent("wheel", {
deltaY,
bubbles: true,
cancelable: true,
});
viewport.dispatchEvent(event);
return event.defaultPrevented;
};
const maxLeft = viewport.scrollWidth - viewport.clientWidth;
viewport.scrollLeft = Math.floor(maxLeft / 2);
expect(dispatchWheel(200)).toBe(true);
viewport.scrollLeft = maxLeft;
expect(dispatchWheel(200)).toBe(false);
viewport.scrollLeft = 0;
expect(dispatchWheel(-200)).toBe(false);
},
};
export const MarkdownAndLinksLight: Story = {
globals: {
theme: "light",
@@ -2091,7 +2091,7 @@ export const ReadFileTallAndWide: Story = {
canvas.getByRole("button", { name: /Read config.ts/i }),
);
await expectDiffText(canvasElement, "apiUrl");
const viewport = await waitFor(() => {
await waitFor(() => {
const target = [
...canvasElement.querySelectorAll<HTMLElement>(
"[data-radix-scroll-area-viewport]",
@@ -2102,13 +2102,7 @@ export const ReadFileTallAndWide: Story = {
if (!target) {
throw new Error("Expected a viewport overflowing on both axes.");
}
return target;
});
viewport.dispatchEvent(
new WheelEvent("wheel", { deltaY: 200, bubbles: true, cancelable: true }),
);
await new Promise((resolve) => setTimeout(resolve, 400));
expect(viewport.scrollLeft).toBe(0);
},
};