CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-udecode--plate-dnd

React drag and drop plugin for Plate rich-text editor enabling block rearrangement and file drops

Pending
Overview
Eval results
Files

auto-scrolling.mddocs/

Auto-scrolling Components

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.

Capabilities

DndScroller

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>
  );
}

Scroller

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>
  );
}

ScrollArea

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')
      }}
    />
  );
}

Advanced Configuration

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>
  );
}

Internal Implementation Notes

The ScrollArea component uses several techniques for smooth scrolling:

  • Throttled Updates: Mouse position is sampled at ~100ms intervals to reduce performance impact
  • RAF-based Animation: Uses requestAnimationFrame for smooth 60fps scrolling
  • Strength Calculation: Scroll speed varies based on mouse proximity to the edge
  • Container Support: Can scroll either the window or a specific container element
  • Touch Support: Includes support for touch-based drag operations

Types

export 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

docs

auto-scrolling.md

component-utilities.md

drag-drop-hooks.md

editor-transforms.md

index.md

plugin-configuration.md

utility-functions.md

tile.json