React drag and drop plugin for Plate rich-text editor enabling block rearrangement and file drops
—
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.
The main auto-scrolling component that integrates with the DndPlugin to provide automatic scrolling during drag operations.
/**
* Auto-scrolling component for drag operations
* Automatically appears during drag operations and provides edge scrolling
* @param props - Configuration props for scrolling behavior
* @returns JSX element providing auto-scroll functionality
*/
export function DndScroller(props: Partial<ScrollerProps>): JSX.Element;Usage Examples:
import { DndPlugin, DndScroller } from "@udecode/plate-dnd";
import { createPlateEditor } from "@udecode/plate/react";
// Automatic integration via plugin configuration
const editor = createPlateEditor({
plugins: [
DndPlugin.configure({
options: {
enableScroller: true,
scrollerProps: {
height: 120,
strengthMultiplier: 30,
minStrength: 0.2
}
}
})
]
});
// Manual usage (if needed for custom integration)
function CustomEditor() {
const isDragging = usePluginOption(DndPlugin, 'isDragging');
return (
<div>
<PlateEditor />
{isDragging && (
<DndScroller
height={100}
strengthMultiplier={25}
zIndex={9999}
/>
)}
</div>
);
}Base scroller component that provides the core scrolling functionality with configurable scroll areas.
/**
* Base scroller component with top and bottom scroll areas
* Sets up scroll zones at the top and bottom of the viewport
* @param props - Scroller configuration options
* @returns JSX element with scroll areas
*/
export function Scroller(props: ScrollerProps): JSX.Element;
export type ScrollerProps = Omit<ScrollAreaProps, 'placement'>;Usage Examples:
import { Scroller } from "@udecode/plate-dnd";
function CustomScrollingArea() {
const [enabled, setEnabled] = useState(false);
return (
<div>
<button onClick={() => setEnabled(!enabled)}>
{enabled ? 'Disable' : 'Enable'} Scrolling
</button>
<Scroller
enabled={enabled}
height={80}
strengthMultiplier={20}
minStrength={0.1}
/>
</div>
);
}Individual scroll area component that can be positioned at different locations (top, bottom, left, right).
/**
* Individual scroll area component
* Creates a single scrolling zone with customizable behavior
* @param options - Scroll area configuration
* @returns JSX element or null if disabled
*/
export function ScrollArea({
placement,
containerRef,
enabled,
height,
minStrength,
scrollAreaProps,
strengthMultiplier,
zIndex
}: ScrollAreaProps): JSX.Element | null;
export interface ScrollAreaProps {
/** Position of the scroll area */
placement: 'bottom' | 'top';
/** Reference to the container to scroll (defaults to window) */
containerRef?: React.RefObject<any>;
/** Whether the scroll area is enabled */
enabled?: boolean;
/** Height of the scroll area in pixels */
height?: number;
/** Minimum scroll strength (0-1) */
minStrength?: number;
/** Additional props for the scroll area div */
scrollAreaProps?: React.HTMLAttributes<HTMLDivElement>;
/** Multiplier for scroll speed */
strengthMultiplier?: number;
/** Z-index for the scroll area */
zIndex?: number;
}Usage Examples:
import { ScrollArea } from "@udecode/plate-dnd";
// Basic scroll areas
function BasicScrollAreas() {
const [enabled, setEnabled] = useState(true);
return (
<>
<ScrollArea
placement="top"
enabled={enabled}
height={60}
strengthMultiplier={15}
/>
<ScrollArea
placement="bottom"
enabled={enabled}
height={60}
strengthMultiplier={15}
/>
</>
);
}
// Custom container scrolling
function CustomContainerScroll() {
const containerRef = useRef<HTMLDivElement>(null);
const [isDragging, setIsDragging] = useState(false);
return (
<div
ref={containerRef}
style={{
height: '400px',
overflow: 'auto',
border: '1px solid #ddd'
}}
>
<div style={{ height: '1000px', padding: '20px' }}>
Long scrollable content...
{isDragging && (
<>
<ScrollArea
placement="top"
containerRef={containerRef}
enabled={true}
height={40}
strengthMultiplier={10}
minStrength={0.3}
/>
<ScrollArea
placement="bottom"
containerRef={containerRef}
enabled={true}
height={40}
strengthMultiplier={10}
minStrength={0.3}
/>
</>
)}
</div>
</div>
);
}
// Custom styling and behavior
function CustomScrollArea() {
return (
<ScrollArea
placement="top"
enabled={true}
height={100}
strengthMultiplier={30}
minStrength={0.1}
zIndex={10000}
scrollAreaProps={{
style: {
backgroundColor: 'rgba(0, 120, 204, 0.1)',
border: '2px dashed #007acc'
},
onMouseEnter: () => console.log('Entered scroll area'),
onMouseLeave: () => console.log('Left scroll area')
}}
/>
);
}The auto-scrolling system can be finely tuned for different use cases:
// High-sensitivity scrolling for precise control
const preciseDndScroller = (
<DndScroller
height={150}
strengthMultiplier={40}
minStrength={0.05}
zIndex={9999}
/>
);
// Low-sensitivity scrolling for stable operation
const stableDndScroller = (
<DndScroller
height={80}
strengthMultiplier={15}
minStrength={0.4}
/>
);
// Custom container scrolling setup
function CustomScrollingEditor() {
const editorRef = useRef<HTMLDivElement>(null);
return (
<div
ref={editorRef}
style={{ height: '500px', overflow: 'auto' }}
>
<PlateEditor />
<Scroller
containerRef={editorRef}
height={60}
strengthMultiplier={20}
minStrength={0.2}
/>
</div>
);
}The ScrollArea component uses several techniques for smooth scrolling:
requestAnimationFrame for smooth 60fps scrollingexport interface ScrollerProps {
containerRef?: React.RefObject<any>;
enabled?: boolean;
height?: number;
minStrength?: number;
scrollAreaProps?: React.HTMLAttributes<HTMLDivElement>;
strengthMultiplier?: number;
zIndex?: number;
}
export interface ScrollAreaProps {
placement: 'bottom' | 'top';
containerRef?: React.RefObject<any>;
enabled?: boolean;
height?: number;
minStrength?: number;
scrollAreaProps?: React.HTMLAttributes<HTMLDivElement>;
strengthMultiplier?: number;
zIndex?: number;
}Install with Tessl CLI
npx tessl i tessl/npm-udecode--plate-dnd