Horizontal Scroll
more-shadcn-noair/horizontal-scrollFreeComponent
Converts vertical mouse wheel scrolling into horizontal scrolling.
Live preview
live · rendered by the registry
Rendered by more-shadcn-noair on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://more-shadcn.noair.fun/r/horizontal-scroll.jsonSource
1<script lang="ts">2 import { cn } from '$UTILS$';3 import { setScrollContext } from './ctx';4 import type { Snippet } from 'svelte';5 import { onMount } from 'svelte';67 let {8 class: className,9 sensitivity = 1.5,10 damping = 0.1,11 children12 }: {13 class?: string;14 sensitivity?: number;15 damping?: number;16 children: Snippet;17 } = $props();1819 let scrollContainer: HTMLDivElement | undefined = $state();2021 let targetScroll = 0;22 let currentScroll = 0;23 let isAnimating = false;24 let animationFrame: number;2526 onMount(() => {27 return () => {28 if (animationFrame) cancelAnimationFrame(animationFrame);29 };30 });3132 function update() {33 if (!scrollContainer) return;3435 const diff = targetScroll - currentScroll;3637 if (Math.abs(diff) < 0.5) {38 currentScroll = targetScroll;39 scrollContainer.scrollLeft = currentScroll;40 isAnimating = false;41 return;42 }4344 currentScroll += diff * damping;45 scrollContainer.scrollLeft = currentScroll;4647 animationFrame = requestAnimationFrame(update);48 }4950 function handleWheel(e: WheelEvent) {51 if (!scrollContainer) return;52 if (e.deltaY === 0) return;5354 const maxScroll = scrollContainer.scrollWidth - scrollContainer.clientWidth;55 if (maxScroll <= 0) return;5657 e.preventDefault();5859 if (!isAnimating) {60 currentScroll = scrollContainer.scrollLeft;61 targetScroll = currentScroll;62 isAnimating = true;63 animationFrame = requestAnimationFrame(update);64 }6566 targetScroll += e.deltaY * sensitivity;6768 targetScroll = Math.max(0, Math.min(targetScroll, maxScroll));69 }7071 setScrollContext({72 scrollLeft: () => {73 if (!scrollContainer) return;74 if (!isAnimating) {75 currentScroll = scrollContainer.scrollLeft;76 targetScroll = currentScroll;77 isAnimating = true;78 animationFrame = requestAnimationFrame(update);79 }80 targetScroll = Math.max(0, targetScroll - 300);81 },82 scrollRight: () => {83 if (!scrollContainer) return;84 const maxScroll = scrollContainer.scrollWidth - scrollContainer.clientWidth;85 if (!isAnimating) {86 currentScroll = scrollContainer.scrollLeft;87 targetScroll = currentScroll;88 isAnimating = true;89 animationFrame = requestAnimationFrame(update);90 }91 targetScroll = Math.min(maxScroll, targetScroll + 300);92 },93 getElement: () => scrollContainer94 });95</script>9697<div98 bind:this={scrollContainer}99 onwheel={handleWheel}100 class={cn('flex w-full overflow-x-auto overflow-y-hidden select-none', className)}101 style="scrollbar-width: none; -ms-overflow-style: none;"102>103// … truncated
What it pulls in
Other registry items
More from more-shadcn-noair
All 43 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Audioaudio | more-shadcn-noair | Components | Free | no deps | |
| Audio Waveaudio-wave | more-shadcn-noair | Components | Free | no deps | |
| Autocompleteautocomplete | more-shadcn-noair | Components | Free | no deps | |
| Bannerbanner | more-shadcn-noair | Components | Free | no deps | |
| Big Calendarbig-calendar | more-shadcn-noair | Components | Free | no deps | |
| Bottom Navigationbottom-nav | more-shadcn-noair | Components | Free | no deps | |
| Canvascanvas | more-shadcn-noair | Components | Free | no deps | |
| Chipchip | more-shadcn-noair | Components | Free | no deps |
