🧮 Functional scaffold for DnD grid
This commit is contained in:
@@ -19,27 +19,7 @@ import { getComicBookDetailById } from "../actions/comicinfo.actions";
|
|||||||
import { detectTradePaperbacks } from "../shared/utils/tradepaperback.utils";
|
import { detectTradePaperbacks } from "../shared/utils/tradepaperback.utils";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
const prettyBytes = require("pretty-bytes");
|
const prettyBytes = require("pretty-bytes");
|
||||||
// https://codesandbox.io/s/dndkit-sortable-image-grid-py6ve?file=/src/Grid.jsx
|
import { DnD } from "./DnD";
|
||||||
import {
|
|
||||||
DndContext,
|
|
||||||
closestCenter,
|
|
||||||
MouseSensor,
|
|
||||||
TouchSensor,
|
|
||||||
DragOverlay,
|
|
||||||
useSensor,
|
|
||||||
useSensors,
|
|
||||||
} from "@dnd-kit/core";
|
|
||||||
import {
|
|
||||||
arrayMove,
|
|
||||||
SortableContext,
|
|
||||||
rectSortingStrategy,
|
|
||||||
} from "@dnd-kit/sortable";
|
|
||||||
|
|
||||||
import { Grid } from "./Grid";
|
|
||||||
import { SortableCover } from "./SortableCover";
|
|
||||||
import { Cover } from "./Cover";
|
|
||||||
import photos from "./photos.json";
|
|
||||||
|
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import {
|
import {
|
||||||
removeLeadingPeriod,
|
removeLeadingPeriod,
|
||||||
@@ -62,10 +42,6 @@ export const ComicDetail = ({}: ComicDetailProps): ReactElement => {
|
|||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const [slidingPanelContentId, setSlidingPanelContentId] = useState("");
|
const [slidingPanelContentId, setSlidingPanelContentId] = useState("");
|
||||||
|
|
||||||
const [items, setItems] = useState(photos);
|
|
||||||
const [activeId, setActiveId] = useState(null);
|
|
||||||
const sensors = useSensors(useSensor(MouseSensor), useSensor(TouchSensor));
|
|
||||||
|
|
||||||
const comicVineSearchResults = useSelector(
|
const comicVineSearchResults = useSelector(
|
||||||
(state: RootState) => state.comicInfo.searchResults,
|
(state: RootState) => state.comicInfo.searchResults,
|
||||||
);
|
);
|
||||||
@@ -158,29 +134,6 @@ export const ComicDetail = ({}: ComicDetailProps): ReactElement => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
function handleDragStart(event) {
|
|
||||||
setActiveId(event.active.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleDragEnd(event) {
|
|
||||||
const { active, over } = event;
|
|
||||||
|
|
||||||
if (active.id !== over.id) {
|
|
||||||
setItems((items) => {
|
|
||||||
const oldIndex = items.indexOf(active.id);
|
|
||||||
const newIndex = items.indexOf(over.id);
|
|
||||||
|
|
||||||
return arrayMove(items, oldIndex, newIndex);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
console.log(items);
|
|
||||||
setActiveId(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleDragCancel() {
|
|
||||||
setActiveId(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
const openDrawerWithCVMatches = useCallback(() => {
|
const openDrawerWithCVMatches = useCallback(() => {
|
||||||
dispatch(fetchComicVineMatches(comicBookDetailData));
|
dispatch(fetchComicVineMatches(comicBookDetailData));
|
||||||
setSlidingPanelContentId("CVMatches");
|
setSlidingPanelContentId("CVMatches");
|
||||||
@@ -262,31 +215,9 @@ export const ComicDetail = ({}: ComicDetailProps): ReactElement => {
|
|||||||
id: 2,
|
id: 2,
|
||||||
icon: <i className="fas fa-file-archive"></i>,
|
icon: <i className="fas fa-file-archive"></i>,
|
||||||
name: "Archive Operations",
|
name: "Archive Operations",
|
||||||
content: (
|
content: <div key={2}>
|
||||||
<div key={2}>
|
<DnD />
|
||||||
<DndContext
|
</div>,
|
||||||
sensors={sensors}
|
|
||||||
collisionDetection={closestCenter}
|
|
||||||
onDragStart={handleDragStart}
|
|
||||||
onDragEnd={handleDragEnd}
|
|
||||||
onDragCancel={handleDragCancel}
|
|
||||||
>
|
|
||||||
<SortableContext items={items} strategy={rectSortingStrategy}>
|
|
||||||
<Grid columns={4}>
|
|
||||||
{items.map((url, index) => (
|
|
||||||
<SortableCover key={url} url={url} index={index} />
|
|
||||||
))}
|
|
||||||
</Grid>
|
|
||||||
</SortableContext>
|
|
||||||
|
|
||||||
<DragOverlay adjustScale={true}>
|
|
||||||
{activeId ? (
|
|
||||||
<Cover url={activeId} index={items.indexOf(activeId)} />
|
|
||||||
) : null}
|
|
||||||
</DragOverlay>
|
|
||||||
</DndContext>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
|
|||||||
75
src/client/components/DnD.tsx
Normal file
75
src/client/components/DnD.tsx
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import React, { ReactElement, useState } from "react";
|
||||||
|
// https://codesandbox.io/s/dndkit-sortable-image-grid-py6ve?file=/src/Grid.jsx
|
||||||
|
import {
|
||||||
|
DndContext,
|
||||||
|
closestCenter,
|
||||||
|
MouseSensor,
|
||||||
|
TouchSensor,
|
||||||
|
DragOverlay,
|
||||||
|
useSensor,
|
||||||
|
useSensors,
|
||||||
|
} from "@dnd-kit/core";
|
||||||
|
import {
|
||||||
|
arrayMove,
|
||||||
|
SortableContext,
|
||||||
|
rectSortingStrategy,
|
||||||
|
} from "@dnd-kit/sortable";
|
||||||
|
|
||||||
|
import { Grid } from "./Grid";
|
||||||
|
import { SortableCover } from "./SortableCover";
|
||||||
|
import { Cover } from "./Cover";
|
||||||
|
import photos from "./photos.json";
|
||||||
|
|
||||||
|
export const DnD = () => {
|
||||||
|
const [items, setItems] = useState(photos);
|
||||||
|
const [activeId, setActiveId] = useState(null);
|
||||||
|
const sensors = useSensors(useSensor(MouseSensor), useSensor(TouchSensor));
|
||||||
|
|
||||||
|
function handleDragStart(event) {
|
||||||
|
setActiveId(event.active.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDragEnd(event) {
|
||||||
|
const { active, over } = event;
|
||||||
|
|
||||||
|
if (active.id !== over.id) {
|
||||||
|
setItems((items) => {
|
||||||
|
const oldIndex = items.indexOf(active.id);
|
||||||
|
const newIndex = items.indexOf(over.id);
|
||||||
|
|
||||||
|
return arrayMove(items, oldIndex, newIndex);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
console.log(items);
|
||||||
|
setActiveId(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDragCancel() {
|
||||||
|
setActiveId(null);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<DndContext
|
||||||
|
sensors={sensors}
|
||||||
|
collisionDetection={closestCenter}
|
||||||
|
onDragStart={handleDragStart}
|
||||||
|
onDragEnd={handleDragEnd}
|
||||||
|
onDragCancel={handleDragCancel}
|
||||||
|
>
|
||||||
|
<SortableContext items={items} strategy={rectSortingStrategy}>
|
||||||
|
<Grid columns={4}>
|
||||||
|
{items.map((url, index) => (
|
||||||
|
<SortableCover key={url} url={url} index={index} />
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
</SortableContext>
|
||||||
|
|
||||||
|
<DragOverlay adjustScale={true}>
|
||||||
|
{activeId ? (
|
||||||
|
<Cover url={activeId} index={items.indexOf(activeId)} />
|
||||||
|
) : null}
|
||||||
|
</DragOverlay>
|
||||||
|
</DndContext>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DnD;
|
||||||
Reference in New Issue
Block a user