1.0.0 • Published 4 months ago
react-jnj v1.0.0
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
1.0.0
4 months ago