@svelte-put/dragscroll
Installation
npm install --save-dev @svelte-put/dragscroll
pnpm add -D @svelte-put/dragscroll
yarn add -D @svelte-put/dragscroll
Quick Start
Typically, use:dragscroll
should be placed on the scroll container.
Below is a minimal demo of dragscroll
with default options. Try scrolling horizontally by pressing and dragging your mouse within the chessboard-patterned box.
<script>
import { dragscroll } from '@svelte-put/dragscroll';
</script>
<div class="overflow-x-auto" use:dragscroll>
{#each new Array(10) as _, row}
<div class="grid grid-cols-[repeat(10,1fr)]">
{#each new Array(10) as _, col}
<div
class="
grid h-10 w-32 place-items-center
{row % 2 === 0
? 'odd:bg-black odd:text-white even:bg-white even:text-black'
: 'odd:bg-white odd:text-black even:bg-black even:text-white'}
"
>
{row * 10 + col + 1}
</div>
{/each}
</div>
{/each}
</div>
Specifying the Scroll Axis
dragscroll
supports both axes. you can specifying one or both scrolling axes using the axis
option. By default, axis
is set to x
.
Select the scroll axis
<script lang="ts">
import { dragscroll, type DragScrollParameters } from '@svelte-put/dragscroll';
let axis: DragScrollParameters['axis'] = 'both';
</script>
<div class="grid place-items-center">
<div class="flex items-center space-x-4">
<p>Select the scroll axis</p>
<label class="cursor-pointer flex items-center gap-2">
<input class="c-input" type="radio" name="axis" value="x" id="x" bind:group={axis} />
x
</label>
<label class="cursor-pointer flex items-center gap-2">
<input class="c-input" type="radio" name="axis" value="y" id="y" bind:group={axis} />
y
</label>
<label class="cursor-pointer flex items-center gap-2">
<input class="c-input" type="radio" name="axis" value="both" id="both" bind:group={axis} />
both
</label>
</div>
<div
class="max-h-[300px] max-w-[300px] overflow-x-auto md:max-h-[400px] md:max-w-[400px] mt-4"
use:dragscroll={{ axis }}
>
{#each new Array(10) as _, row}
<div class="grid grid-cols-[repeat(10,1fr)]">
{#each new Array(10) as _, col}
<div
class="
grid h-20 w-20 place-items-center
{row % 2 === 0
? 'odd:bg-black odd:text-white even:bg-white even:text-black'
: 'odd:bg-white odd:text-black even:bg-black even:text-white'}
"
>
{row * 10 + col + 1}
</div>
{/each}
</div>
{/each}
</div>
</div>
mouse
vs pointer
By default, dragscroll
assumes PointerEvent, i.e pointerup
, pointerdown
, pointermove
, pointerleave
. You can switch to MouseEvent equivalents by setting the event
option to mouse
.
<div use:dragscroll={{ event: 'pointer' }}>...</div>
<div use:dragscroll={{ event: 'mouse' }}>...</div>
Disable Cursor Handling
By default, dragscroll
adds cursor: grab
to the node the action is placed on, and similarly, cursor: grabbing
on mousedown
. This can be disabled by setting the cursor
option to false
(default is true
).
<div use:dragscroll={{ cursor: false }}>...</div>
Limitation
There is a known issue when dragscroll
is used with scroll-snap-align, where the scroll container tends to be unresponsive to dragscroll
and requires a great mousemove
length to snap to the next box.
In the example below, try using the scrollbar to confirm scroll-snap-align
has been set up. Then, try dragging with mouse and notice that it only works when the mouse is dragged over almost the entire width of the container.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
If you find a solution or workaround to the above, please consider open a PR or discussion thread. Thank you!
Happy dragging! 👨💻