返回 AiToEarn
1 /**
2 * PublishDialogDragSource - 发布弹框左栏拖拽源包装组件
3 * 仅在发布弹框内启用,避免普通草稿页缺少 DndProvider 时触发 react-dnd 上下文错误。
4 */
5
6 'use client'
7
8 import type { HTMLAttributes, ReactNode } from 'react'
9 import type { DragSourceMonitor } from 'react-dnd'
10 import type { PublishDialogDragItem } from '@/components/PublishDialog/PublishDialog.util'
11 import { memo, useEffect } from 'react'
12 import { useDrag } from 'react-dnd'
13 import { getEmptyImage } from 'react-dnd-html5-backend'
14 import { PUBLISH_DIALOG_DND_TYPE } from '@/components/PublishDialog/PublishDialog.util'
15 import { cn } from '@/utils/className'
16
17 interface PublishDialogDragSourceProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
18 dragItem: PublishDialogDragItem
19 children: ReactNode
20 }
21
22 export const PublishDialogDragSource = memo(({ dragItem, className, children, ...props }: PublishDialogDragSourceProps) => {
23 const [{ isDragging }, drag, preview] = useDrag(
24 () => ({
25 type: PUBLISH_DIALOG_DND_TYPE,
26 item: dragItem,
27 collect: (monitor: DragSourceMonitor) => ({
28 isDragging: monitor.isDragging(),
29 }),
30 }),
31 [dragItem],
32 )
33
34 useEffect(() => {
35 preview(getEmptyImage(), { captureDraggingState: true })
36 }, [preview])
37
38 return (
39 <div
40 ref={(node) => {
41 drag(node)
42 }}
43 className={cn(className, 'cursor-grab active:cursor-grabbing', isDragging && 'opacity-50')}
44 {...props}
45 >
46 {children}
47 </div>
48 )
49 })
50
51 PublishDialogDragSource.displayName = 'PublishDialogDragSource'
52
52 lines Plain Text