0
# Auto-scrolling Components
1
2
Components that provide automatic viewport scrolling when dragging near screen edges. These components enhance the user experience during drag operations by automatically scrolling the viewport when the user drags items near the top or bottom of the visible area.
3
4
## Capabilities
5
6
### DndScroller
7
8
The main auto-scrolling component that integrates with the DndPlugin to provide automatic scrolling during drag operations.
9
10
```typescript { .api }
11
/**
12
* Auto-scrolling component for drag operations
13
* Automatically appears during drag operations and provides edge scrolling
14
* @param props - Configuration props for scrolling behavior
15
* @returns JSX element providing auto-scroll functionality
16
*/
17
export function DndScroller(props: Partial<ScrollerProps>): JSX.Element;
18
```
19
20
**Usage Examples:**
21
22
```typescript
23
import { DndPlugin, DndScroller } from "@udecode/plate-dnd";
24
import { createPlateEditor } from "@udecode/plate/react";
25
26
// Automatic integration via plugin configuration
27
const editor = createPlateEditor({
28
plugins: [
29
DndPlugin.configure({
30
options: {
31
enableScroller: true,
32
scrollerProps: {
33
height: 120,
34
strengthMultiplier: 30,
35
minStrength: 0.2
36
}
37
}
38
})
39
]
40
});
41
42
// Manual usage (if needed for custom integration)
43
function CustomEditor() {
44
const isDragging = usePluginOption(DndPlugin, 'isDragging');
45
46
return (
47
<div>
48
<PlateEditor />
49
{isDragging && (
50
<DndScroller
51
height={100}
52
strengthMultiplier={25}
53
zIndex={9999}
54
/>
55
)}
56
</div>
57
);
58
}
59
```
60
61
### Scroller
62
63
Base scroller component that provides the core scrolling functionality with configurable scroll areas.
64
65
```typescript { .api }
66
/**
67
* Base scroller component with top and bottom scroll areas
68
* Sets up scroll zones at the top and bottom of the viewport
69
* @param props - Scroller configuration options
70
* @returns JSX element with scroll areas
71
*/
72
export function Scroller(props: ScrollerProps): JSX.Element;
73
74
export type ScrollerProps = Omit<ScrollAreaProps, 'placement'>;
75
```
76
77
**Usage Examples:**
78
79
```typescript
80
import { Scroller } from "@udecode/plate-dnd";
81
82
function CustomScrollingArea() {
83
const [enabled, setEnabled] = useState(false);
84
85
return (
86
<div>
87
<button onClick={() => setEnabled(!enabled)}>
88
{enabled ? 'Disable' : 'Enable'} Scrolling
89
</button>
90
91
<Scroller
92
enabled={enabled}
93
height={80}
94
strengthMultiplier={20}
95
minStrength={0.1}
96
/>
97
</div>
98
);
99
}
100
```
101
102
### ScrollArea
103
104
Individual scroll area component that can be positioned at different locations (top, bottom, left, right).
105
106
```typescript { .api }
107
/**
108
* Individual scroll area component
109
* Creates a single scrolling zone with customizable behavior
110
* @param options - Scroll area configuration
111
* @returns JSX element or null if disabled
112
*/
113
export function ScrollArea({
114
placement,
115
containerRef,
116
enabled,
117
height,
118
minStrength,
119
scrollAreaProps,
120
strengthMultiplier,
121
zIndex
122
}: ScrollAreaProps): JSX.Element | null;
123
124
export interface ScrollAreaProps {
125
/** Position of the scroll area */
126
placement: 'bottom' | 'top';
127
/** Reference to the container to scroll (defaults to window) */
128
containerRef?: React.RefObject<any>;
129
/** Whether the scroll area is enabled */
130
enabled?: boolean;
131
/** Height of the scroll area in pixels */
132
height?: number;
133
/** Minimum scroll strength (0-1) */
134
minStrength?: number;
135
/** Additional props for the scroll area div */
136
scrollAreaProps?: React.HTMLAttributes<HTMLDivElement>;
137
/** Multiplier for scroll speed */
138
strengthMultiplier?: number;
139
/** Z-index for the scroll area */
140
zIndex?: number;
141
}
142
```
143
144
**Usage Examples:**
145
146
```typescript
147
import { ScrollArea } from "@udecode/plate-dnd";
148
149
// Basic scroll areas
150
function BasicScrollAreas() {
151
const [enabled, setEnabled] = useState(true);
152
153
return (
154
<>
155
<ScrollArea
156
placement="top"
157
enabled={enabled}
158
height={60}
159
strengthMultiplier={15}
160
/>
161
162
<ScrollArea
163
placement="bottom"
164
enabled={enabled}
165
height={60}
166
strengthMultiplier={15}
167
/>
168
</>
169
);
170
}
171
172
// Custom container scrolling
173
function CustomContainerScroll() {
174
const containerRef = useRef<HTMLDivElement>(null);
175
const [isDragging, setIsDragging] = useState(false);
176
177
return (
178
<div
179
ref={containerRef}
180
style={{
181
height: '400px',
182
overflow: 'auto',
183
border: '1px solid #ddd'
184
}}
185
>
186
<div style={{ height: '1000px', padding: '20px' }}>
187
Long scrollable content...
188
189
{isDragging && (
190
<>
191
<ScrollArea
192
placement="top"
193
containerRef={containerRef}
194
enabled={true}
195
height={40}
196
strengthMultiplier={10}
197
minStrength={0.3}
198
/>
199
200
<ScrollArea
201
placement="bottom"
202
containerRef={containerRef}
203
enabled={true}
204
height={40}
205
strengthMultiplier={10}
206
minStrength={0.3}
207
/>
208
</>
209
)}
210
</div>
211
</div>
212
);
213
}
214
215
// Custom styling and behavior
216
function CustomScrollArea() {
217
return (
218
<ScrollArea
219
placement="top"
220
enabled={true}
221
height={100}
222
strengthMultiplier={30}
223
minStrength={0.1}
224
zIndex={10000}
225
scrollAreaProps={{
226
style: {
227
backgroundColor: 'rgba(0, 120, 204, 0.1)',
228
border: '2px dashed #007acc'
229
},
230
onMouseEnter: () => console.log('Entered scroll area'),
231
onMouseLeave: () => console.log('Left scroll area')
232
}}
233
/>
234
);
235
}
236
```
237
238
### Advanced Configuration
239
240
The auto-scrolling system can be finely tuned for different use cases:
241
242
```typescript
243
// High-sensitivity scrolling for precise control
244
const preciseDndScroller = (
245
<DndScroller
246
height={150}
247
strengthMultiplier={40}
248
minStrength={0.05}
249
zIndex={9999}
250
/>
251
);
252
253
// Low-sensitivity scrolling for stable operation
254
const stableDndScroller = (
255
<DndScroller
256
height={80}
257
strengthMultiplier={15}
258
minStrength={0.4}
259
/>
260
);
261
262
// Custom container scrolling setup
263
function CustomScrollingEditor() {
264
const editorRef = useRef<HTMLDivElement>(null);
265
266
return (
267
<div
268
ref={editorRef}
269
style={{ height: '500px', overflow: 'auto' }}
270
>
271
<PlateEditor />
272
273
<Scroller
274
containerRef={editorRef}
275
height={60}
276
strengthMultiplier={20}
277
minStrength={0.2}
278
/>
279
</div>
280
);
281
}
282
```
283
284
## Internal Implementation Notes
285
286
The ScrollArea component uses several techniques for smooth scrolling:
287
288
- **Throttled Updates**: Mouse position is sampled at ~100ms intervals to reduce performance impact
289
- **RAF-based Animation**: Uses `requestAnimationFrame` for smooth 60fps scrolling
290
- **Strength Calculation**: Scroll speed varies based on mouse proximity to the edge
291
- **Container Support**: Can scroll either the window or a specific container element
292
- **Touch Support**: Includes support for touch-based drag operations
293
294
## Types
295
296
```typescript { .api }
297
export interface ScrollerProps {
298
containerRef?: React.RefObject<any>;
299
enabled?: boolean;
300
height?: number;
301
minStrength?: number;
302
scrollAreaProps?: React.HTMLAttributes<HTMLDivElement>;
303
strengthMultiplier?: number;
304
zIndex?: number;
305
}
306
307
export interface ScrollAreaProps {
308
placement: 'bottom' | 'top';
309
containerRef?: React.RefObject<any>;
310
enabled?: boolean;
311
height?: number;
312
minStrength?: number;
313
scrollAreaProps?: React.HTMLAttributes<HTMLDivElement>;
314
strengthMultiplier?: number;
315
zIndex?: number;
316
}
317
```