1.0.0 • Published 4 months ago

react-jnj v1.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
4 months ago

React PnP (拖放库)

一个简单、高效的React拖放组件库,支持自定义拖放交互。

特点

  • 💡 简单API - 易于学习和使用的API
  • 🧩 组件化 - 可组合的组件设计
  • 🔄 灵活性 - 支持高度自定义拖放行为
  • 📦 轻量级 - 最小化依赖
  • 🔍 类型安全 - 完整的TypeScript支持

安装

npm install react-jnj

基本用法

引入必要的组件

import { DragDropProvider, DragItem } from 'react-jnj';

设置拖放上下文

function App() {
  return (
    <DragDropProvider>
      {/* 你的应用内容 */}
    </DragDropProvider>
  );
}

创建可拖放的组件

function DraggableComponent() {
  return (
    <DragItem
      isDraggable={true}
      dragType="CARD"
      dragData={{ id: 'card-1', content: '这是一张卡片' }}
    >
      {({ isDragging }) => (
        <div className={isDragging ? 'dragging' : ''}>
          拖动我!
        </div>
      )}
    </DragItem>
  );
}

创建放置区域

function DropZone() {
  const handleDrop = (item) => {
    console.log('放置了:', item);
  };

  return (
    <DragItem
      isDroppable={true}
      accepts={['CARD']}
      dropListeners={{ onDrop: handleDrop }}
    >
      {({ isOver, canDrop }) => (
        <div className={`drop-zone ${isOver ? 'over' : ''} ${canDrop ? 'can-drop' : ''}`}>
          将卡片放在这里
        </div>
      )}
    </DragItem>
  );
}

高级用法

使用钩子实现自定义拖放

import { useDrag, useDrop } from 'react-jnj';

function CustomDragItem() {
  const { isDragging, dragSourceRef, dragHandleProps } = useDrag({
    type: 'CUSTOM',
    item: { id: 'custom-1' },
    listeners: {
      onDragStart: () => console.log('开始拖动'),
      onDragEnd: () => console.log('结束拖动')
    }
  });

  return (
    <div 
      ref={dragSourceRef} 
      {...dragHandleProps}
      style={{ opacity: isDragging ? 0.5 : 1 }}
    >
      自定义拖动项
    </div>
  );
}

function CustomDropTarget() {
  const { isOver, canDrop, dropTargetRef, dropTargetProps } = useDrop({
    accept: ['CUSTOM'],
    listeners: {
      onDrop: (item) => console.log('放置了:', item)
    }
  });

  return (
    <div 
      ref={dropTargetRef} 
      {...dropTargetProps}
      style={{ 
        background: isOver ? (canDrop ? 'lightgreen' : 'lightpink') : 'white'
      }}
    >
      自定义放置区
    </div>
  );
}

创建可排序列表

import { useState } from 'react';
import { DragDropProvider, DragItem } from 'react-jnj';

function SortableList() {
  const [items, setItems] = useState([
    { id: '1', text: '项目 1' },
    { id: '2', text: '项目 2' },
    { id: '3', text: '项目 3' },
  ]);

  const moveItem = (dragId, hoverId) => {
    const dragIndex = items.findIndex(item => item.id === dragId);
    const hoverIndex = items.findIndex(item => item.id === hoverId);
    
    if (dragIndex === -1 || hoverIndex === -1) return;
    
    const newItems = [...items];
    const dragItem = newItems[dragIndex];
    
    // 移除拖动的项
    newItems.splice(dragIndex, 1);
    // 在新位置插入
    newItems.splice(hoverIndex, 0, dragItem);
    
    setItems(newItems);
  };

  return (
    <div className="sortable-list">
      {items.map(item => (
        <DragItem
          key={item.id}
          isDraggable={true}
          isDroppable={true}
          dragType="LIST_ITEM"
          dragData={item}
          accepts={['LIST_ITEM']}
          dropListeners={{
            onDrop: (draggedItem) => moveItem(draggedItem.id, item.id)
          }}
        >
          <div className="list-item">
            {item.text}
          </div>
        </DragItem>
      ))}
    </div>
  );
}

API参考

组件

<DragDropProvider>

提供拖放上下文。

<DragDropProvider>
  {/* 你的应用内容 */}
</DragDropProvider>

<DragItem>

合并的拖放组件,可同时作为拖拽源和放置目标。

Props:

  • isDraggable (boolean): 是否可拖动
  • dragType (string): 拖动项类型
  • dragData (any): 与拖动项关联的数据
  • dragListeners (object): 拖动事件监听器
    • onDragStart: 拖动开始时的回调
    • onDragEnd: 拖动结束时的回调
  • isDroppable (boolean): 是否可接受放置
  • accepts (string | string[]): 可接受的拖动项类型
  • dropListeners (object): 放置事件监听器
    • onDragEnter: 拖动进入时的回调
    • onDragLeave: 拖动离开时的回调
    • onDragOver: 拖动悬停时的回调
    • onDrop: 放置时的回调
  • children: 渲染函数或React节点
  • className (string): 自定义类名
  • style (object): 自定义样式

钩子

useDrag

用于创建自定义拖动源的钩子。

const { isDragging, dragSourceRef, dragHandleProps } = useDrag(options);

Options:

  • type (string): 拖动项类型
  • item (any): 拖动项数据
  • listeners (object): 事件监听器
    • onDragStart: 拖动开始时的回调
    • onDragEnd: 拖动结束时的回调

返回值:

  • isDragging (boolean): 是否正在拖动
  • dragSourceRef (React.RefObject): 拖动源引用
  • dragHandleProps (object): 拖动处理属性

useDrop

用于创建自定义放置目标的钩子。

const { isOver, canDrop, dropTargetRef, dropTargetProps } = useDrop(options);

Options:

  • accept (string | string[]): 可接受的拖动项类型
  • listeners (object): 事件监听器
    • onDragEnter: 拖动进入时的回调
    • onDragLeave: 拖动离开时的回调
    • onDragOver: 拖动悬停时的回调
    • onDrop: 放置时的回调

返回值:

  • isOver (boolean): 是否有拖动项悬停在上方
  • canDrop (boolean): 是否可以放置当前拖动项
  • dropTargetRef (React.RefObject): 放置目标引用
  • dropTargetProps (object): 放置目标属性

许可证

MIT