React component that implements drag-to-scroll functionality for content containers
npx @tessl/cli install tessl/npm-react-indiana-drag-scroll@2.2.00
# React Indiana Drag Scroll
1
2
React Indiana Drag Scroll implements scroll on drag functionality for React applications. It enables users to scroll through content by clicking and dragging, similar to the scrolling behavior found in mobile applications or Adobe PDF viewers. The component provides comprehensive customization options for scrolling behavior, visual feedback, and interaction controls.
3
4
## Package Information
5
6
- **Package Name**: react-indiana-drag-scroll
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install react-indiana-drag-scroll`
10
11
## Core Imports
12
13
```typescript
14
import ScrollContainer from "react-indiana-drag-scroll";
15
import { ScrollEvent } from "react-indiana-drag-scroll";
16
```
17
18
For CommonJS:
19
20
```javascript
21
const ScrollContainer = require("react-indiana-drag-scroll");
22
```
23
24
## Basic Usage
25
26
```typescript
27
import React from "react";
28
import ScrollContainer from "react-indiana-drag-scroll";
29
30
function App() {
31
return (
32
<ScrollContainer className="scroll-container">
33
<div style={{ width: "2000px", height: "1000px" }}>
34
{/* Your scrollable content here */}
35
<h1>Drag to scroll this large content area</h1>
36
</div>
37
</ScrollContainer>
38
);
39
}
40
```
41
42
## Capabilities
43
44
### ScrollContainer Component
45
46
The main React component that wraps content to provide drag-to-scroll functionality.
47
48
```typescript { .api }
49
export default class ScrollContainer extends React.PureComponent<ScrollContainerProps> {
50
/** Returns the HTML element of the scroll container */
51
getElement(): HTMLElement;
52
}
53
```
54
55
### ScrollContainer Props
56
57
Configuration options for the ScrollContainer component.
58
59
```typescript { .api }
60
interface ScrollContainerProps {
61
/** Enable vertical drag scrolling (default: true) */
62
vertical?: boolean;
63
/** Enable horizontal drag scrolling (default: true) */
64
horizontal?: boolean;
65
/** Hide the scrollbars (default: true) */
66
hideScrollbars?: boolean;
67
/** Distance to distinguish click vs drag in pixels (default: 10) */
68
activationDistance?: number;
69
/** Content to be scrolled */
70
children?: ReactNode;
71
/** Callback when scrolling starts */
72
onStartScroll?: (event: ScrollEvent) => void;
73
/** Callback during scrolling */
74
onScroll?: (event: ScrollEvent) => void;
75
/** Callback when scrolling ends */
76
onEndScroll?: (event: ScrollEvent) => void;
77
/** Callback for click without drag */
78
onClick?: (event: MouseEvent) => void;
79
/** CSS class for container */
80
className?: string;
81
/** CSS class applied during dragging */
82
draggingClassName?: string;
83
/** Inline styles for container */
84
style?: CSSProperties;
85
/** CSS selector for elements to ignore dragging */
86
ignoreElements?: string;
87
/** Use native mobile scrolling on mobile devices (default: true) */
88
nativeMobileScroll?: boolean;
89
/** React ref */
90
ref?: ReactNode;
91
/** Root component type (default: 'div') */
92
component?: ElementType;
93
/** Alternative ref mechanism */
94
innerRef?: Ref<HTMLElement>;
95
/** Stop event propagation for mouse and touch events (default: false) */
96
stopPropagation?: boolean;
97
/** Mouse buttons that trigger scrolling (default: [0] - left button) */
98
buttons?: number[];
99
}
100
```
101
102
### ScrollEvent Interface
103
104
Event object passed to scroll callback functions.
105
106
```typescript { .api }
107
interface ScrollEvent {
108
/** Indicates if scroll was triggered externally (not by drag) */
109
external: boolean;
110
}
111
```
112
113
### Scroll Lifecycle Callbacks
114
115
#### onStartScroll
116
117
Called when drag scrolling begins.
118
119
```typescript { .api }
120
onStartScroll?: (event: ScrollEvent) => void;
121
```
122
123
#### onScroll
124
125
Called continuously during scrolling (both drag and native scroll events).
126
127
```typescript { .api }
128
onScroll?: (event: ScrollEvent) => void;
129
```
130
131
#### onEndScroll
132
133
Called when scrolling stops (with debounce delay).
134
135
```typescript { .api }
136
onEndScroll?: (event: ScrollEvent) => void;
137
```
138
139
### Advanced Configuration
140
141
#### Custom Activation Distance
142
143
Control how far the mouse must move before drag scrolling activates:
144
145
```typescript
146
<ScrollContainer activationDistance={20}>
147
{content}
148
</ScrollContainer>
149
```
150
151
#### Disable Scrollbar Visibility
152
153
Show native scrollbars:
154
155
```typescript
156
<ScrollContainer hideScrollbars={false}>
157
{content}
158
</ScrollContainer>
159
```
160
161
#### Directional Scrolling
162
163
Enable only horizontal or vertical scrolling:
164
165
```typescript
166
{/* Horizontal only */}
167
<ScrollContainer vertical={false}>
168
{content}
169
</ScrollContainer>
170
171
{/* Vertical only */}
172
<ScrollContainer horizontal={false}>
173
{content}
174
</ScrollContainer>
175
```
176
177
#### Ignore Specific Elements
178
179
Prevent drag scrolling on certain elements:
180
181
```typescript
182
<ScrollContainer ignoreElements="button, .modal, input">
183
<div>
184
<button>This won't trigger drag scroll</button>
185
<div className="modal">Neither will this</div>
186
</div>
187
</ScrollContainer>
188
```
189
190
#### Multi-Button Support
191
192
Configure which mouse buttons trigger scrolling:
193
194
```typescript
195
{/* Right-click and middle-click scrolling */}
196
<ScrollContainer buttons={[1, 2]}>
197
{content}
198
</ScrollContainer>
199
```
200
201
#### Custom Component Type
202
203
Use a different root element:
204
205
```typescript
206
<ScrollContainer component="section" className="custom-scroll-section">
207
{content}
208
</ScrollContainer>
209
```
210
211
#### Access DOM Element
212
213
Get the underlying HTML element:
214
215
```typescript
216
import React, { useRef, useEffect } from "react";
217
import ScrollContainer from "react-indiana-drag-scroll";
218
219
function MyComponent() {
220
const scrollRef = useRef<ScrollContainer>(null);
221
222
useEffect(() => {
223
if (scrollRef.current) {
224
const element = scrollRef.current.getElement();
225
// Set initial scroll position
226
element.scrollLeft = 100;
227
element.scrollTop = 50;
228
}
229
}, []);
230
231
return (
232
<ScrollContainer ref={scrollRef}>
233
{content}
234
</ScrollContainer>
235
);
236
}
237
```
238
239
### Event Handling
240
241
Track scroll events with detailed callbacks:
242
243
```typescript
244
import React from "react";
245
import ScrollContainer, { ScrollEvent } from "react-indiana-drag-scroll";
246
247
function ScrollableContent() {
248
const handleScrollStart = (event: ScrollEvent) => {
249
console.log("Scroll started", { external: event.external });
250
};
251
252
const handleScroll = (event: ScrollEvent) => {
253
console.log("Scrolling", { external: event.external });
254
};
255
256
const handleScrollEnd = (event: ScrollEvent) => {
257
console.log("Scroll ended", { external: event.external });
258
};
259
260
const handleClick = (event: MouseEvent) => {
261
console.log("Clicked without dragging");
262
};
263
264
return (
265
<ScrollContainer
266
onStartScroll={handleScrollStart}
267
onScroll={handleScroll}
268
onEndScroll={handleScrollEnd}
269
onClick={handleClick}
270
>
271
{content}
272
</ScrollContainer>
273
);
274
}
275
```
276
277
### CSS Styling
278
279
The component applies several CSS classes for styling:
280
281
- `indiana-scroll-container` - Base component class
282
- `indiana-scroll-container--dragging` - Applied during drag operations
283
- `indiana-scroll-container--hide-scrollbars` - Applied when hideScrollbars is true
284
- `indiana-scroll-container--native-scroll` - Applied on mobile devices
285
- `indiana-dragging` - Added to document.body during drag
286
287
Custom styling can be applied via the `className`, `draggingClassName`, and `style` props.
288
289
## Types
290
291
```typescript { .api }
292
interface ScrollContainerProps {
293
vertical?: boolean;
294
horizontal?: boolean;
295
hideScrollbars?: boolean;
296
activationDistance?: number;
297
children?: ReactNode;
298
onStartScroll?: (event: ScrollEvent) => void;
299
onScroll?: (event: ScrollEvent) => void;
300
onEndScroll?: (event: ScrollEvent) => void;
301
onClick?: (event: MouseEvent) => void;
302
className?: string;
303
draggingClassName?: string;
304
style?: CSSProperties;
305
ignoreElements?: string;
306
nativeMobileScroll?: boolean;
307
ref?: ReactNode;
308
component?: ElementType;
309
innerRef?: Ref<HTMLElement>;
310
stopPropagation?: boolean;
311
buttons?: number[];
312
}
313
314
interface ScrollEvent {
315
external: boolean;
316
}
317
```