From 824927cb776bbaaf712e9b1f7f5be72e6a489034 Mon Sep 17 00:00:00 2001 From: neodk2004 Date: Sun, 16 Aug 2026 13:45:07 +0200 Subject: [PATCH] fix(explore): support mouse-wheel scrolling on desktop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hiding the scrollbar (previous commit) removed the only desktop affordance for moving a horizontally-scrolling, scrollbar-hidden row — mouse wheel scrolls vertically by default and there's no drag handle anymore. Adds useHorizontalScroll, which redirects vertical wheel delta to scrollLeft while leaving trackpad horizontal gestures and touch swipe untouched. Applied to the explore species tabs and StoryTray, which had the identical latent issue. --- src/app/(app)/explore/page.tsx | 8 +++++++- src/components/stories/StoryTray.tsx | 4 ++++ src/hooks/use-horizontal-scroll.ts | 27 +++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 src/hooks/use-horizontal-scroll.ts diff --git a/src/app/(app)/explore/page.tsx b/src/app/(app)/explore/page.tsx index c1424f1..6c94c21 100644 --- a/src/app/(app)/explore/page.tsx +++ b/src/app/(app)/explore/page.tsx @@ -7,6 +7,7 @@ import { useInfiniteQuery, useQuery } from "@tanstack/react-query"; import { Loader2, TrendingUp } from "lucide-react"; import { useTRPC } from "@/trpc/client"; import { useActivePet } from "@/context/ActivePetContext"; +import { useHorizontalScroll } from "@/hooks/use-horizontal-scroll"; import { ExploreCard } from "@/components/explore/ExploreCard"; import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Badge } from "@/components/ui/badge"; @@ -32,6 +33,7 @@ export default function ExplorePage() { const [activeTab, setActiveTab] = useState("trending"); const [activeBreedId, setActiveBreedId] = useState(null); const [selectedPost, setSelectedPost] = useState(null); + const speciesTabsScroll = useHorizontalScroll(); const isTrending = activeTab === "trending"; const activeSpeciesId = @@ -94,7 +96,11 @@ export default function ExplorePage() {

{t("title")}

-
+
diff --git a/src/components/stories/StoryTray.tsx b/src/components/stories/StoryTray.tsx index 1e2c147..111e594 100644 --- a/src/components/stories/StoryTray.tsx +++ b/src/components/stories/StoryTray.tsx @@ -6,6 +6,7 @@ import { useTranslations } from "next-intl"; import { useQuery } from "@tanstack/react-query"; import { useTRPC } from "@/trpc/client"; import { useActivePet } from "@/context/ActivePetContext"; +import { useHorizontalScroll } from "@/hooks/use-horizontal-scroll"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Dialog, @@ -34,6 +35,7 @@ export function StoryTray() { const trpc = useTRPC(); const { activePetId } = useActivePet(); + const trayScroll = useHorizontalScroll(); const [addStoryOpen, setAddStoryOpen] = useState(false); const [viewingPet, setViewingPet] = useState<{ id: string; @@ -53,6 +55,8 @@ export function StoryTray() { <> {/* Horizontal scroll tray */}
() { + const ref = useRef(null); + + const onWheel = useCallback((e: WheelEvent) => { + const el = ref.current; + if (!el || el.scrollWidth <= el.clientWidth) return; + if (Math.abs(e.deltaY) <= Math.abs(e.deltaX)) return; + + el.scrollLeft += e.deltaY; + e.preventDefault(); + }, []); + + return { ref, onWheel }; +}