Files
spacedrive/interface/app/$libraryId/Explorer/DragOverlay.tsx
Utku 9a1cdf1dca Fix all the weird eslint warnings (#2245)
* actually fix the weird lint errors

* Prettier auto-format

---------

Co-authored-by: ameer2468 <33054370+ameer2468@users.noreply.github.com>
Co-authored-by: Vítor Vasconcellos <vasconcellos.dev@gmail.com>
2024-03-26 20:46:44 +00:00

98 lines
2.8 KiB
TypeScript

import type { ClientRect, Modifier } from '@dnd-kit/core';
import { DragOverlay as DragOverlayPrimitive } from '@dnd-kit/core';
import { getEventCoordinates } from '@dnd-kit/utilities';
import clsx from 'clsx';
import { memo, useEffect, useRef } from 'react';
import { ExplorerItem, useSelector } from '@sd/client';
import { useIsDark } from '~/hooks';
import { FileThumb } from './FilePath/Thumb';
import { explorerStore } from './store';
import { RenamableItemText } from './View/RenamableItemText';
const useSnapToCursorModifier = () => {
const drag = useSelector(explorerStore, (s) => s.drag);
const initialRect = useRef<ClientRect | null>(null);
const modifier: Modifier = ({ activatorEvent, activeNodeRect, transform }) => {
if (!activeNodeRect || !activatorEvent) return transform;
const activatorCoordinates = getEventCoordinates(activatorEvent);
if (!activatorCoordinates) return transform;
const rect = initialRect.current ?? activeNodeRect;
if (!initialRect.current) initialRect.current = activeNodeRect;
// Default offset so during drag the cursor doesn't overlap the overlay
// which can cause issues with mouse events on other elements
const offset = 12;
const offsetX = activatorCoordinates.x - rect.left;
const offsetY = activatorCoordinates.y - rect.top;
return {
...transform,
x: transform.x + offsetX + offset,
y: transform.y + offsetY + offset
};
};
useEffect(() => {
if (!drag) initialRect.current = null;
}, [drag]);
return modifier;
};
export const DragOverlay = memo(() => {
const isDark = useIsDark();
const modifier = useSnapToCursorModifier();
const drag = useSelector(explorerStore, (s) => s.drag);
return (
<DragOverlayPrimitive
dropAnimation={null}
modifiers={[modifier]}
className="!h-auto !w-full max-w-md"
>
{!drag || drag.type === 'touched' ? null : (
<div className="space-y-[2px] pl-0.5 pt-0.5 duration-300 animate-in fade-in">
{drag.items.length > 1 && (
<div className="absolute right-full top-1.5 mr-2 flex h-6 min-w-[24px] items-center justify-center rounded-full bg-accent px-1 text-sm text-white">
{drag.items.length}
</div>
)}
{(drag.items.slice(0, 8) as ExplorerItem[]).map((item, i, items) => (
<div
key={i}
className={clsx(
'flex items-center gap-2',
drag.items.length > 7 && [
i + 1 === items.length && 'opacity-10',
i + 2 === items.length && 'opacity-50',
i + 3 === items.length && 'opacity-90'
]
)}
>
<FileThumb
data={item}
size={32}
frame
frameClassName={clsx(
'!border-DEFAULT shadow-md',
isDark ? 'shadow-app-shade/50' : 'shadow-app-shade/25'
)}
/>
<RenamableItemText item={item} highlight={true} />
</div>
))}
</div>
)}
</DragOverlayPrimitive>
);
});