/** * @author Timur Kuzhagaliyev * @copyright 2020 * @license MIT */ import React from 'react'; import { useDragLayer } from 'react-dnd'; import { Nullable } from 'tsdef'; import { ChonkyDndFileEntryItem, ChonkyDndFileEntryType } from '../../types/dnd.types'; import { makeGlobalChonkyStyles } from '../../util/styles'; export interface DnDFileListDragLayerProps {} const layerStyles: React.CSSProperties = { position: 'fixed', pointerEvents: 'none', zIndex: 100, left: 0, top: 0, width: '100%', height: '100%', }; const getItemStyles = ( initialCursorOffset: Nullable<{ x: number; y: number }>, initialFileOffset: Nullable<{ x: number; y: number }>, currentFileOffset: Nullable<{ x: number; y: number }>, ) => { if (!initialCursorOffset || !initialFileOffset || !currentFileOffset) { return { display: 'none', }; } const x = initialCursorOffset.x + (currentFileOffset.x - initialFileOffset.x); const y = initialCursorOffset.y + (currentFileOffset.y - initialFileOffset.y); const transform = `translate(${x}px, ${y}px)`; return { transform, WebkitTransform: transform, }; }; export const DnDFileListDragLayer: React.FC = () => { const classes = useStyles(); const { itemType, item, initialCursorOffset, initialFileOffset, currentFileOffset, isDragging } = useDragLayer( (monitor) => ({ item: monitor.getItem() as ChonkyDndFileEntryItem, itemType: monitor.getItemType(), initialCursorOffset: monitor.getInitialClientOffset(), initialFileOffset: monitor.getInitialSourceClientOffset(), currentFileOffset: monitor.getSourceClientOffset(), isDragging: monitor.isDragging(), }), ); if (!isDragging || itemType !== ChonkyDndFileEntryType || !item.payload) { return null; } const selectionSize = item.payload.selectedFiles.length; return (
{item.payload.draggedFile.name} {selectionSize > 1 && ( <> {' and '} {selectionSize - 1} other file {selectionSize - 1 !== 1 ? 's' : ''} )}
); }; const useStyles = makeGlobalChonkyStyles((theme) => ({ fileDragPreview: { boxShadow: `2px 2px 5px ${theme.palette.divider}`, backgroundColor: theme.palette.background.default, borderRadius: theme.dragLayer.borderRadius, fontSize: theme.fontSizes.rootPrimary, color: theme.palette.text.primary, padding: theme.dragLayer.padding, border: theme.dragLayer.border, display: 'inline-block', }, }));