1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-24 20:36:40 +07:00

added useSortableActions hook

This commit is contained in:
Fedor Katurov 2022-06-24 17:56:05 +07:00
parent 3345939670
commit 586ebb7480
7 changed files with 86 additions and 72 deletions

View file

@ -0,0 +1,15 @@
import React, { FC } from 'react';
import classNames from 'classnames';
import styles from './styles.module.scss';
interface DragOverlayItemProps {
className?: string;
}
const DragOverlayItem: FC<DragOverlayItemProps> = ({ className, children }) => (
<div className={classNames(styles.overlay, className)}>{children}</div>
);
export { DragOverlayItem };

View file

@ -0,0 +1,6 @@
@import "src/styles/variables";
.overlay {
box-shadow: rgba(0, 0, 0, 0.3) 5px 5px 10px 2px;
border-radius: $radius;
}

View file

@ -14,6 +14,8 @@ import { DragEndEvent } from '@dnd-kit/core/dist/types';
import { rectSortingStrategy, SortableContext } from '@dnd-kit/sortable'; import { rectSortingStrategy, SortableContext } from '@dnd-kit/sortable';
import classNames from 'classnames'; import classNames from 'classnames';
import { DragOverlayItem } from '~/components/sortable/DragOverlayItem';
import { useSortableActions } from '~/hooks/sortable';
import { moveArrItem } from '~/utils/fn'; import { moveArrItem } from '~/utils/fn';
import { DivProps } from '~/utils/types'; import { DivProps } from '~/utils/types';
@ -44,47 +46,10 @@ const SortableGrid = <T, R>({
onSortEnd, onSortEnd,
size, size,
}: SortableGridProps<T, R>) => { }: SortableGridProps<T, R>) => {
const [draggingItem, setDraggingItem] = useState<T | null>(null); const { sensors, onDragEnd, onDragStart, draggingItem, ids } = useSortableActions(
items,
const ids = useMemo(() => items.map(getID), [items]); getID,
onSortEnd
const onDragEnd = useCallback(
({ active, over }: DragEndEvent) => {
setDraggingItem(null);
if (!over?.id || active.id === over.id) {
return;
}
const oldIndex = items.findIndex(it => getID(it) === active.id);
const newIndex = items.findIndex(it => getID(it) === over.id);
onSortEnd(moveArrItem(oldIndex, newIndex, items));
},
[items]
);
const onDragStart = useCallback(
({ active }: DragStartEvent) => {
if (!active.id) {
return;
}
const activeItem = items.find(it => getID(it) === active.id);
setDraggingItem(activeItem ?? null);
},
[items]
);
const sensors = useSensors(
useSensor(TouchSensor, {
activationConstraint: {
delay: 200,
tolerance: 5,
},
}),
useSensor(MouseSensor)
); );
const gridStyle = useMemo<DivProps['style']>( const gridStyle = useMemo<DivProps['style']>(
@ -122,9 +87,7 @@ const SortableGrid = <T, R>({
<DragOverlay> <DragOverlay>
{draggingItem ? ( {draggingItem ? (
<div className={styles.overlay}> <DragOverlayItem>{createElement(renderItem, { item: draggingItem })}</DragOverlayItem>
{createElement(renderItem, { item: draggingItem })}
</div>
) : null} ) : null}
</DragOverlay> </DragOverlay>
</div> </div>

View file

@ -9,11 +9,6 @@
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
} }
.overlay {
box-shadow: rgba(0, 0, 0, 0.3) 5px 5px 10px 2px;
border-radius: $radius;
}
.dragging { .dragging {
opacity: 0.1; opacity: 0.1;
} }

View file

@ -1,23 +0,0 @@
@import "src/styles/variables";
.grid {
box-sizing: border-box;
display: grid;
grid-column-gap: $gap;
grid-row-gap: $gap;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
@media (max-width: 600px) {
grid-template-columns: repeat(auto-fill, minmax(30vw, 1fr));
}
}
.overlay {
box-shadow: rgba(0, 0, 0, 0.3) 5px 5px 10px 2px;
border-radius: $radius;
}
.dragging {
opacity: 0.1;
}

View file

@ -0,0 +1 @@
export * from './useSortableActions';

View file

@ -0,0 +1,57 @@
import { useCallback, useMemo, useState } from 'react';
import { DragStartEvent, MouseSensor, TouchSensor, useSensor, useSensors } from '@dnd-kit/core';
import { DragEndEvent } from '@dnd-kit/core/dist/types';
import { moveArrItem } from '~/utils/fn';
export const useSortableActions = <T>(
items: T[],
getID: (item: T) => string | number,
onSortEnd: (items: T[]) => void
) => {
const [draggingItem, setDraggingItem] = useState<T | null>(null);
const ids = useMemo(() => items.map(getID), [items]);
const onDragEnd = useCallback(
({ active, over }: DragEndEvent) => {
setDraggingItem(null);
if (!over?.id || active.id === over.id) {
return;
}
const oldIndex = items.findIndex(it => getID(it) === active.id);
const newIndex = items.findIndex(it => getID(it) === over.id);
onSortEnd(moveArrItem(oldIndex, newIndex, items));
},
[items]
);
const onDragStart = useCallback(
({ active }: DragStartEvent) => {
if (!active.id) {
return;
}
const activeItem = items.find(it => getID(it) === active.id);
setDraggingItem(activeItem ?? null);
},
[items]
);
const sensors = useSensors(
useSensor(TouchSensor, {
activationConstraint: {
delay: 200,
tolerance: 5,
},
}),
useSensor(MouseSensor)
);
return { sensors, onDragEnd, onDragStart, draggingItem, ids };
};