or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

array-utilities.mdindex.mdsortable-container.mdsortable-element.mdsortable-handle.md
tile.json

tessl/npm-react-sortable-hoc

Higher-order components to turn any list into animated, accessible and touch-friendly sortable lists

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/react-sortable-hoc@2.0.x

To install, run

npx @tessl/cli install tessl/npm-react-sortable-hoc@2.0.0

index.mddocs/

React Sortable HOC

React Sortable HOC is a set of higher-order components that transform any list into animated, accessible, and touch-friendly sortable lists. It provides smooth 60 FPS animations with drag handles, auto-scrolling, axis locking, keyboard navigation, and extensive event handling for creating sophisticated interactive UI components.

Package Information

  • Package Name: react-sortable-hoc
  • Package Type: npm
  • Language: JavaScript/TypeScript
  • Installation: npm install react-sortable-hoc

Core Imports

import { SortableContainer, SortableElement, SortableHandle, arrayMove, isSortableHandle, SortableContext } from 'react-sortable-hoc';

Alternative lowercase imports (identical functionality):

import { sortableContainer, sortableElement, sortableHandle } from 'react-sortable-hoc';

Note: The lowercase imports are aliases for the uppercase versions and provide identical functionality.

For CommonJS:

const { SortableContainer, SortableElement, SortableHandle, arrayMove, isSortableHandle, SortableContext } = require('react-sortable-hoc');

Basic Usage

import React, { Component } from 'react';
import { SortableContainer, SortableElement } from 'react-sortable-hoc';
import { arrayMove } from 'array-move';

const SortableItem = SortableElement(({ value }) => <li>{value}</li>);

const SortableList = SortableContainer(({ items }) => {
  return (
    <ul>
      {items.map((value, index) => (
        <SortableItem key={`item-${value}`} index={index} value={value} />
      ))}
    </ul>
  );
});

class SortableComponent extends Component {
  state = {
    items: ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6'],
  };
  
  onSortEnd = ({ oldIndex, newIndex }) => {
    this.setState(({ items }) => ({
      items: arrayMove(items, oldIndex, newIndex),
    }));
  };
  
  render() {
    return <SortableList items={this.state.items} onSortEnd={this.onSortEnd} />;
  }
}

Architecture

React Sortable HOC is built around several key components:

  • Higher-Order Components: Three main HOCs (SortableContainer, SortableElement, SortableHandle) that enhance existing React components with sortable functionality
  • Event System: Comprehensive mouse, touch, and keyboard event handling with customizable callbacks
  • Animation Engine: 60 FPS animations using CSS transforms with configurable transition durations
  • Manager System: Internal state management for tracking sortable elements and coordinating drag operations
  • Auto-Scrolling: Automatic container scrolling during drag operations with customizable thresholds
  • Accessibility: Full keyboard navigation support with ARIA-friendly interactions

Capabilities

Sortable Container

Higher-order component that makes any component capable of containing sortable elements. Provides comprehensive configuration for animations, constraints, events, and behavior.

function SortableContainer<P>(
  wrappedComponent: WrappedComponent<P>,
  config?: Config
): React.ComponentClass<P & SortableContainerProps>;

interface SortableContainerProps {
  axis?: 'x' | 'y' | 'xy';
  lockAxis?: 'x' | 'y';
  helperClass?: string;
  transitionDuration?: number;
  keyboardSortingTransitionDuration?: number;
  pressDelay?: number;
  pressThreshold?: number;
  distance?: number;
  shouldCancelStart?: (event: SortEvent | SortEventWithTag) => boolean;
  updateBeforeSortStart?: SortStartHandler;
  onSortStart?: SortStartHandler;
  onSortMove?: SortMoveHandler;
  onSortEnd?: SortEndHandler;
  onSortOver?: SortOverHandler;
  useDragHandle?: boolean;
  useWindowAsScrollContainer?: boolean;
  hideSortableGhost?: boolean;
  lockToContainerEdges?: boolean;
  lockOffset?: Offset | [Offset, Offset];
  getContainer?: ContainerGetter;
  getHelperDimensions?: (sort: SortStart) => Dimensions;
  helperContainer?: HTMLElement | HelperContainerGetter;
  disableAutoscroll?: boolean;
  keyCodes?: {
    lift?: number[];
    drop?: number[];
    cancel?: number[];
    up?: number[];
    down?: number[];
  };
}

Sortable Container

Sortable Element

Higher-order component that makes individual elements sortable within a SortableContainer. Simple interface focused on positioning and state management.

function SortableElement<P>(
  wrappedComponent: WrappedComponent<P>,
  config?: Config
): React.ComponentClass<P & SortableElementProps>;

interface SortableElementProps {
  index: number;
  collection?: Offset;
  disabled?: boolean;
}

Sortable Element

Sortable Handle

Higher-order component that creates designated drag areas within sortable elements. Enables fine-grained control over drag initiation.

function SortableHandle<P>(
  wrappedComponent: WrappedComponent<P>,
  config?: Config
): React.ComponentClass<P>;

Sortable Handle

Array Utilities

Utility function for reordering arrays after sort operations (deprecated - use separate 'array-move' package).

function arrayMove<T>(
  collection: T[],
  previousIndex: number,
  newIndex: number
): T[];

Array Utilities

Utility Functions

Helper functions and context for working with sortable handles and drag state.

function isSortableHandle(node: Element): boolean;

const SortableContext: React.Context<{
  manager: Manager;
}>;

Types

type Axis = 'x' | 'y' | 'xy';
type Offset = number | string;
type SortEvent = React.MouseEvent<any> | React.TouchEvent<any>;

interface SortStart {
  node: Element;
  index: number;
  collection: Offset;
  isKeySorting: boolean;
  nodes: HTMLElement[];
  helper: HTMLElement;
}

interface SortOver {
  index: number;
  oldIndex: number;
  newIndex: number;
  collection: Offset;
  isKeySorting: boolean;
  nodes: HTMLElement[];
  helper: HTMLElement;
}

interface SortEnd {
  oldIndex: number;
  newIndex: number;
  collection: Offset;
  isKeySorting: boolean;
  nodes: HTMLElement[];
}

interface Dimensions {
  width: number;
  height: number;
}

interface Config {
  withRef: boolean;
}

type WrappedComponent<P> =
  | React.ComponentClass<P>
  | React.SFC<P>
  | WrappedComponentFactory<P>;

type WrappedComponentFactory<P> = (props: P) => JSX.Element;

type SortStartHandler = (sort: SortStart, event: SortEvent) => void;
type SortMoveHandler = (event: SortEvent) => void;
type SortEndHandler = (sort: SortEnd, event: SortEvent) => void;
type SortOverHandler = (sort: SortOver, event: SortEvent) => void;
type ContainerGetter = (element: React.ReactElement<any>) => HTMLElement | Promise<HTMLElement>;
type HelperContainerGetter = () => HTMLElement;

interface Manager {
  refs: { [key: string]: HTMLElement };
}