feat: swiper for boards on desktop

This commit is contained in:
2025-08-16 19:57:22 +04:00
parent a4bcd62189
commit 2e9ed02722
5 changed files with 116 additions and 68 deletions

View File

@ -11,6 +11,8 @@ import { Active, DndContext, DragEndEvent } from "@dnd-kit/core";
import { restrictToHorizontalAxis } from "@dnd-kit/modifiers";
import { SortableContext } from "@dnd-kit/sortable";
import { LexoRank } from "lexorank";
import { FreeMode, Mousewheel, Scrollbar } from "swiper/modules";
import { Swiper, SwiperSlide } from "swiper/react";
import { Box, Flex } from "@mantine/core";
import useDndSensors from "@/app/deals/hooks/useSensors";
import { SortableOverlay } from "@/components/dnd/SortableDnd/SortableOverlay";
@ -35,6 +37,7 @@ type Props<T extends BaseItem> = {
containerStyle?: CSSProperties;
vertical?: boolean;
disabled?: boolean;
swiperEnabled?: boolean;
};
const SortableDnd = <T extends BaseItem>({
@ -45,8 +48,9 @@ const SortableDnd = <T extends BaseItem>({
onDragEnd,
onItemClick,
containerStyle,
vertical,
vertical = false,
disabled = false,
swiperEnabled = false,
}: Props<T>) => {
const [active, setActive] = useState<Active | null>(null);
const [items, setItems] = useState<T[]>([]);
@ -98,6 +102,81 @@ const SortableDnd = <T extends BaseItem>({
setActive(null);
};
const renderWithSwiper = () => (
<Swiper
modules={[Scrollbar, Mousewheel, FreeMode]}
spaceBetween={15}
slidesPerView={"auto"}
scrollbar={{ hide: false }}
mousewheel={{
enabled: true,
sensitivity: 0.2,
}}
style={containerStyle}
direction={vertical ? "vertical" : "horizontal"}
freeMode={{ enabled: true }}
grabCursor>
{items.map((item, index) => (
<SwiperSlide
style={{ width: "fit-content" }}
key={index}
onClick={e => {
if (!onItemClick) return;
e.stopPropagation();
onItemClick(item);
}}>
<SortableItem
id={item.id}
disabled={disabled}
renderItem={renderDraggable =>
renderItem(item, renderDraggable)
}
renderDraggable={
renderDraggable
? () => renderDraggable(item)
: undefined
}
dragHandleStyle={dragHandleStyle}
/>
</SwiperSlide>
))}
</Swiper>
);
const renderWithFlex = () => (
<Flex
style={{
gap: 0,
flexWrap: "nowrap",
flexDirection: vertical ? "column" : "row",
...containerStyle,
}}>
{items.map((item, index) => (
<Box
key={index}
onClick={e => {
if (!onItemClick) return;
e.stopPropagation();
onItemClick(item);
}}>
<SortableItem
id={item.id}
disabled={disabled}
renderItem={renderDraggable =>
renderItem(item, renderDraggable)
}
renderDraggable={
renderDraggable
? () => renderDraggable(item)
: undefined
}
dragHandleStyle={dragHandleStyle}
/>
</Box>
))}
</Flex>
);
return (
<DndContext
modifiers={[restrictToHorizontalAxis]}
@ -108,37 +187,7 @@ const SortableDnd = <T extends BaseItem>({
<SortableContext
items={items}
disabled={disabled}>
<Flex
style={{
gap: 0,
flexWrap: "nowrap",
flexDirection: vertical ? "column" : "row",
...containerStyle,
}}>
{items.map((item, index) => (
<Box
key={index}
onClick={e => {
if (!onItemClick) return;
e.stopPropagation();
onItemClick(item);
}}>
<SortableItem
id={item.id}
disabled={disabled}
renderItem={renderDraggable =>
renderItem(item, renderDraggable)
}
renderDraggable={
renderDraggable
? () => renderDraggable(item)
: undefined
}
dragHandleStyle={dragHandleStyle}
/>
</Box>
))}
</Flex>
{swiperEnabled ? renderWithSwiper() : renderWithFlex()}
</SortableContext>
<SortableOverlay>
{activeItem ? renderItem(activeItem, renderDraggable) : null}