mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
chore: remove horizontal wheel scrolling (#26332)
This commit is contained in:
@@ -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);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user