ant-design/components/upload/demo/drag-sorting.tsx

116 lines
3.3 KiB
TypeScript

import { UploadOutlined } from '@ant-design/icons';
import type { DragEndEvent } from '@dnd-kit/core';
import { DndContext, PointerSensor, useSensor } from '@dnd-kit/core';
import {
arrayMove,
SortableContext,
useSortable,
verticalListSortingStrategy,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import React, { useState } from 'react';
import { Button, Upload } from 'antd';
import type { UploadFile, UploadProps } from 'antd/es/upload/interface';
interface DraggableUploadListItemProps {
originNode: React.ReactElement<any, string | React.JSXElementConstructor<any>>;
file: UploadFile<any>;
}
const DraggableUploadListItem = ({ originNode, file }: DraggableUploadListItemProps) => {
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
id: file.uid,
});
const style: React.CSSProperties = {
transform: CSS.Transform.toString(transform),
transition,
cursor: 'move',
};
return (
<div
ref={setNodeRef}
style={style}
// prevent preview event when drag end
className={isDragging ? 'is-dragging' : ''}
{...attributes}
{...listeners}
>
{/* hide error tooltip when dragging */}
{file.status === 'error' && isDragging ? originNode.props.children : originNode}
</div>
);
};
const App: React.FC = () => {
const [fileList, setFileList] = useState<UploadFile[]>([
{
uid: '-1',
name: 'image1.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
{
uid: '-2',
name: 'image2.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
{
uid: '-3',
name: 'image3.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
{
uid: '-4',
name: 'image4.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
{
uid: '-5',
name: 'image.png',
status: 'error',
},
]);
const sensor = useSensor(PointerSensor, {
activationConstraint: { distance: 10 },
});
const onDragEnd = ({ active, over }: DragEndEvent) => {
if (active.id !== over?.id) {
setFileList((prev) => {
const activeIndex = prev.findIndex((i) => i.uid === active.id);
const overIndex = prev.findIndex((i) => i.uid === over?.id);
return arrayMove(prev, activeIndex, overIndex);
});
}
};
const onChange: UploadProps['onChange'] = ({ fileList: newFileList }) => {
setFileList(newFileList);
};
return (
<DndContext sensors={[sensor]} onDragEnd={onDragEnd}>
<SortableContext items={fileList.map((i) => i.uid)} strategy={verticalListSortingStrategy}>
<Upload
action="https://run.mocky.io/v3/435e224c-44fb-4773-9faf-380c5e6a2188"
fileList={fileList}
onChange={onChange}
itemRender={(originNode, file) => (
<DraggableUploadListItem originNode={originNode} file={file} />
)}
>
<Button icon={<UploadOutlined />}>Click to Upload</Button>
</Upload>
</SortableContext>
</DndContext>
);
};
export default App;